/* Main method to test math */ int main() { // Test matrix math struct Matrix a; //double valuesa[9] = { 5.0, -2.0, 1.0, 0.0, 3.0, -1.0, 2.0, 0.0, 7.0 }; double valuesa[16] = { 1.0, 3.0, -2.0, 1.0, 5.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -2.0, 2.0, -1.0, 0.0, 3.0 }; newMatrix(&a, valuesa, 4, 4); struct Matrix b; double valuesb[9] = { 1.0, 2.0, 3.0, 0.0, -4.0, 1.0, 0.0, 3.0, -1.0 }; newMatrix(&b, valuesb, 3, 3); struct Matrix cofa; matrixCofactor(&cofa, a); printf("A Cofactor=\n"); matrixToString(cofa); struct Matrix inva; matrixInverse(&inva, a); printf("A Inverse=\n"); matrixToString(inva); printf("A=\n"); matrixToString(a); printf("B=\n"); matrixToString(b); printf("A is %sa square matrix.\n", matrixIsSquare(a) ? "" : "not "); printf("B is %sa square matrix.\n", matrixIsSquare(b) ? "" : "not "); printf("The determinant of A is %f.\n", matrixDeterminant(a)); printf("A is %sunique.\n", matrixIsUnique(a) ? "" : "not "); printf("The determinant of B is %f.\n", matrixDeterminant(b)); printf("B is %sunique.\n", matrixIsUnique(b) ? "" : "not "); struct Matrix aplusb; matrixAdd(&aplusb, a, b); printf("A+B=\n"); matrixToString(aplusb); struct Matrix asubb; matrixSubtract(&asubb, a, b); printf("A-B=\n"); matrixToString(asubb); struct Matrix ascale; matrixScale(&ascale, a, 5); printf("5A=\n"); matrixToString(ascale); struct Matrix bscale; matrixScale(&bscale, b, 5); printf("5B=\n"); matrixToString(bscale); printf("A and B are %sthe same size.\n", matrixIsSameSize(a, b) ? "" : "not "); printf("A=\n"); matrixToString(a); printf("B=\n"); matrixToString(b); // Test 3D vector math }
void feet(float footangle){ matrixPush(ModelView); matrixRotate(ModelView, footangle, 0, 0, 1); matrixPush(ModelView); matrixScale(ModelView, .9, .9, 1); joint(); matrixPop(ModelView); matrixPush(ModelView); matrixScale(ModelView, -1, 1, 1); foot(); matrixPop(ModelView); matrixPop(ModelView); }
void matrixInverse3x3(float matrixC[9], float matrixA[9]) { float det; float transposeA[9]; float minors[9]; float transposeMinors[9]; det = matrixA[0] * (matrixA[4] * matrixA[8] - matrixA[5] * matrixA[7]) - matrixA[1] * (matrixA[3] * matrixA[8] - matrixA[5] * matrixA[6]) + matrixA[2] * (matrixA[3] * matrixA[7] - matrixA[4] * matrixA[6]); matrixTranspose3x3(transposeA, matrixA); minors[0] = matrixA[4] * matrixA[8] - matrixA[5] * matrixA[7]; minors[1] = matrixA[5] * matrixA[6] - matrixA[3] * matrixA[8]; minors[2] = matrixA[3] * matrixA[7] - matrixA[4] * matrixA[6]; minors[3] = matrixA[2] * matrixA[7] - matrixA[1] * matrixA[8]; minors[4] = matrixA[0] * matrixA[8] - matrixA[2] * matrixA[6]; minors[5] = matrixA[1] * matrixA[6] - matrixA[0] * matrixA[7]; minors[6] = matrixA[1] * matrixA[5] - matrixA[2] * matrixA[4]; minors[7] = matrixA[2] * matrixA[3] - matrixA[0] * matrixA[5]; minors[8] = matrixA[0] * matrixA[4] - matrixA[1] * matrixA[3]; matrixTranspose3x3(transposeMinors, minors); det = 1/det; matrixScale(3,3, matrixC, det, transposeMinors); }
static Bool minPaintWindow (CompWindow *w, const WindowPaintAttrib *attrib, const CompTransform *transform, Region region, unsigned int mask) { CompScreen *s = w->screen; Bool status; MIN_SCREEN (s); MIN_WINDOW (w); if (mw->adjust) { FragmentAttrib fragment; CompTransform wTransform = *transform; if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) return FALSE; UNWRAP (ms, s, paintWindow); status = (*s->paintWindow) (w, attrib, transform, region, mask | PAINT_WINDOW_NO_CORE_INSTANCE_MASK); WRAP (ms, s, paintWindow, minPaintWindow); initFragmentAttrib (&fragment, &w->lastPaint); if (w->alpha || fragment.opacity != OPAQUE) mask |= PAINT_WINDOW_TRANSLUCENT_MASK; matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f); matrixScale (&wTransform, mw->xScale, mw->yScale, 1.0f); matrixTranslate (&wTransform, mw->tx / mw->xScale - w->attrib.x, mw->ty / mw->yScale - w->attrib.y, 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*s->drawWindow) (w, &wTransform, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); glPopMatrix (); } else { /* no core instance from windows that have been animated */ if (mw->state == IconicState) mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK; UNWRAP (ms, s, paintWindow); status = (*s->paintWindow) (w, attrib, transform, region, mask); WRAP (ms, s, paintWindow, minPaintWindow); } return status; }
int main() { printf("Testing work:\n"); int n = 9; int m = 1; Matrix a = matrixNew(n, m); for (int i = 0; i < matrixGetRows(a); i++) for (int j = 0; j < matrixGetCols(a); j++) matrixSet(a, i, j, (float)(i + 1) / (j + 1)); for (int i = 0; i < matrixGetRows(a); i++) { for (int j = 0; j < matrixGetCols(a); j++) printf("%.5f ", matrixGet(a, i, j)); printf("\n"); } printf("\n"); Matrix b = matrixScale(a, 10); for (int i = 0; i < matrixGetRows(b); i++) { for (int j = 0; j < matrixGetCols(b); j++) printf("%.5f ", matrixGet(b, i, j)); printf("\n"); } printf("\n"); Matrix c = matrixAdd(a, b); for (int i = 0; i < matrixGetRows(c); i++) { for (int j = 0; j < matrixGetCols(c); j++) printf("%.5f ", matrixGet(c, i, j)); printf("\n"); } printf("\n"); Matrix d = matrixTranspose(c); for (int i = 0; i < matrixGetRows(d); i++) { for (int j = 0; j < matrixGetCols(d); j++) printf("%.5f ", matrixGet(d, i, j)); printf("\n"); } /*c = matrixAdd(a, matrixNew(1, 1)); if (c == NULL) printf("Yeah\n"), c = matrixNew(3, 3);*/ Matrix e = matrixMul(c, d); printf("%i %i\n", matrixGetRows(e), matrixGetCols(e)); for (int i = 0; i < matrixGetRows(e); i++) { for (int j = 0; j < matrixGetCols(e); j++) printf("%.5f ", matrixGet(e, i, j)); printf("\n"); } matrixDelete(a); matrixDelete(b); matrixDelete(c); matrixDelete(d); matrixDelete(e); return 0; }
void arm(float upperarmangle, float lowerarmangle, float wristangle){ matrixPush(ModelView); matrixRotate(ModelView, upperarmangle, 0, 0, 1); matrixPush(ModelView); matrixScale(ModelView, .625, .625, 1); joint(); matrixPop(ModelView); matrixPush(ModelView); matrixScale(ModelView, 1.25, 1, 1); arm_segment(); matrixPop(ModelView); matrixTranslate(ModelView, 0, -6, 0); forearm(lowerarmangle, wristangle); matrixPop(ModelView); }
void lower_leg(float lowerlegangle, float footangle){ matrixPush(ModelView); matrixRotate(ModelView, lowerlegangle, 0, 0, 1); matrixPush(ModelView); matrixScale(ModelView, .9, .9, 1); joint(); matrixPop(ModelView); matrixPush(ModelView); matrixScale(ModelView, 1.8, .8 , 1); arm_segment(); matrixPop(ModelView); matrixTranslate(ModelView, 0, -4.8, 0); feet(footangle); matrixPop(ModelView); }
void Transform::update() const { Matrix4 S = matrixScale(mScale); Matrix4 R = mOrientation.toMatrix(); mCachedMatrix = R * S; mCachedMatrix[0][3] = mPosition.x; mCachedMatrix[1][3] = mPosition.y; mCachedMatrix[2][3] = mPosition.z; inverse(&mCachedInverse, mCachedMatrix); mIsUpdated = true; }
void convexSpaceCenterPos(struct convexSpace *space, struct convexFigList *vertices) { int vertCount=0; matrixZero(space->pos, dim); if (!vertices) return; while (vertices) { matrixAdd(space->pos, vertices->fig->space->pos, dim); vertCount++; vertices=vertices->next; } matrixScale(space->pos, 1.0/vertCount, dim); }
static void applyGlideTransform(CompWindow *w, CompTransform *transform) { ANIM_SCREEN(w->screen); ANIM_WINDOW(w); float finalDistFac; float finalRotAng; float thickness; fxGlideGetParams(as, aw, &finalDistFac, &finalRotAng, &thickness); float forwardProgress; if (fxGlideZoomToTaskBar(as, aw)) { float dummy; fxZoomAnimProgress(as, aw, &forwardProgress, &dummy, TRUE); } else forwardProgress = fxGlideAnimProgress(aw); float finalz = finalDistFac * 0.8 * DEFAULT_Z_CAMERA * w->screen->width; Vector3d rotAxis = {1, 0, 0}; Point3d rotAxisOffset = {WIN_X(w) + WIN_W(w) / 2.0f, WIN_Y(w) + WIN_H(w) / 2.0f, 0}; Point3d translation = {0, 0, finalz * forwardProgress}; float rotAngle = finalRotAng * forwardProgress; aw->glideModRotAngle = fmodf(rotAngle + 720, 360.0f); // put back to window position matrixTranslate (transform, rotAxisOffset.x, rotAxisOffset.y, 0); resetAndPerspectiveDistortOnZ (transform, -1.0 / w->screen->width); // animation movement matrixTranslate (transform, translation.x, translation.y, translation.z); // animation rotation matrixRotate (transform, rotAngle, rotAxis.x, rotAxis.y, rotAxis.z); // intentional scaling of z by 0 to prevent weird opacity results and // flashing that happen when z coords are between 0 and 1 (bug in ecomp?) matrixScale (transform, 1.0f, 1.0f, 0.0f); // place window rotation axis at origin matrixTranslate (transform, -rotAxisOffset.x, -rotAxisOffset.y, 0); }
void fist(float wristangle){ matrixPush(ModelView); matrixRotate(ModelView, wristangle, 0, 0, 1); matrixPush(ModelView); matrixScale(ModelView, .5, .5, 1); joint(); matrixPop(ModelView); hand(); matrixPop(ModelView); }
static void tdApplyScreenTransform (CompScreen *s, const ScreenPaintAttrib *sAttrib, CompOutput *output, CompTransform *transform) { TD_SCREEN (s); UNWRAP (tds, s, applyScreenTransform); (*s->applyScreenTransform) (s, sAttrib, output, transform); WRAP (tds, s, applyScreenTransform, tdApplyScreenTransform); matrixScale (transform, tds->currentScale, tds->currentScale, tds->currentScale); }
void transformToScreenSpace (CompScreen *screen, CompOutput *output, float z, CompTransform *transform) { matrixTranslate (transform, -0.5f, -0.5f, z); matrixScale (transform, 1.0f / output->width, -1.0f / output->height, 1.0f); matrixTranslate (transform, -output->region.extents.x1, -output->region.extents.y2, 0.0f); }
void leg(float upperlegangle, float lowerlegangle, float footangle){ matrixPush(ModelView); matrixRotate(ModelView, upperlegangle, 0, 0, 1); joint(); matrixPush(ModelView); matrixScale(ModelView, 2, 1, 1); arm_segment(); matrixPop(ModelView); matrixTranslate(ModelView, 0, -6, 0); lower_leg(lowerlegangle, footangle); matrixPop(ModelView); }
void forearm(float lowerarmangle, float wristangle){ matrixPush(ModelView); matrixRotate(ModelView, lowerarmangle, 0, 0, 1); matrixPush(ModelView); matrixScale(ModelView, .5, .5, 1); joint(); matrixPop(ModelView); arm_segment(); matrixPush(ModelView); matrixTranslate(ModelView, 0, -6, 0); fist(wristangle); matrixPop(ModelView); matrixPop(ModelView); }
void convexSpaceNormalCalc(struct convexSpace *space, struct convexSpace *inSpace) { int i; for (i=inSpace->dim-1; i>=0; i--) { matrixCopy( inSpace->ortBasis+i*dim, space->normal, dim); matrixOrtVectorToBasis( space->ortBasis, space->normal, space->dim, dim); if (figureDistCmpZeroSq(matrixVectorNormSq(space->normal, dim))!=0) { matrixVectorNormalize(space->normal, dim); break; } } space->normalPos=0; space->normalPos+=convexSpaceOrientedDist(space, space); if (convexSpaceOrientedDist(space, inSpace)>0) { matrixScale(space->normal, -1, dim); space->normalPos*=-1; } }
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); } }
void right_leg(float upperlegangle, float lowerlegangle, float footangle){ matrixPush(ModelView); matrixScale(ModelView, -1, 1, 1); leg(upperlegangle, lowerlegangle, footangle); matrixPop(ModelView); }
void GltSkySphere::draw() const { if (!visible()) return; GLERROR GltViewport viewport(true); // // Setup perspective camera mode, // orthogonal doesn't really work... // glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(_fov,double(viewport.width())/double(viewport.height()), 0.1, 200.0); // // Twiddle the current modelview matrix // to cancel out translation and scale. // glMatrixMode(GL_MODELVIEW); glPushMatrix(); Matrix matrix(GL_MODELVIEW_MATRIX); // No translation matrix[12] = 0.0; matrix[13] = 0.0; matrix[14] = 0.0; // No scale const real sf = sqrt( SQ(matrix[0]) + SQ(matrix[1]) + SQ(matrix[2]) ); matrix *= matrixScale(1.0/sf); // matrix.glLoadMatrix(); transformation().glMultMatrix(); // // // GLERROR glPushAttrib(GL_ENABLE_BIT|GL_POLYGON_BIT|GL_LIGHTING_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_CULL_FACE); if (solid()) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glShadeModel(GL_SMOOTH); } else { glDisable(GL_BLEND); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glShadeModel(GL_FLAT); } // drawSphere(_map,_slices); // glPopAttrib(); GLERROR glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); GLERROR }
static void thumbPaintThumb (CompScreen *s, Thumbnail *t, const CompTransform *transform) { AddWindowGeometryProc oldAddWindowGeometry; CompWindow *w = t->win; int wx = t->x; int wy = t->y; float width = t->width; float height = t->height; WindowPaintAttrib sAttrib; unsigned int mask = PAINT_WINDOW_TRANSFORMED_MASK | PAINT_WINDOW_TRANSLUCENT_MASK; THUMB_SCREEN (s); if (!w) return; sAttrib = w->paint; if (t->textData) height += t->textData->height + TEXT_DISTANCE; /* Wrap drawWindowGeometry to make sure the general drawWindowGeometry function is used */ oldAddWindowGeometry = s->addWindowGeometry; s->addWindowGeometry = addWindowGeometry; if (w->texture->pixmap) { int off = t->offset; GLenum filter = display.textureFilter; FragmentAttrib fragment; CompTransform wTransform = *transform; glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisableClientState (GL_TEXTURE_COORD_ARRAY); const BananaValue * option_window_like = bananaGetOption (bananaIndex, "window_like", s->screenNum); if (option_window_like->b) { glColor4f (1.0, 1.0, 1.0, t->opacity); enableTexture (s, &ts->windowTexture, COMP_TEXTURE_FILTER_GOOD); } else { unsigned short color[] = { 0, 0, 0, 0 }; const BananaValue * option_thumb_color = bananaGetOption (bananaIndex, "thumb_color", s->screenNum); stringToColor (option_thumb_color->s, color); glColor4us (color[0], color[1], color[2], color[3] * t->opacity); enableTexture (s, &ts->glowTexture, COMP_TEXTURE_FILTER_GOOD); } glBegin (GL_QUADS); glTexCoord2f (1, 0); glVertex2f (wx, wy); glVertex2f (wx, wy + height); glVertex2f (wx + width, wy + height); glVertex2f (wx + width, wy); glTexCoord2f (0, 1); glVertex2f (wx - off, wy - off); glTexCoord2f (0, 0); glVertex2f (wx - off, wy); glTexCoord2f (1, 0); glVertex2f (wx, wy); glTexCoord2f (1, 1); glVertex2f (wx, wy - off); glTexCoord2f (1, 1); glVertex2f (wx + width, wy - off); glTexCoord2f (1, 0); glVertex2f (wx + width, wy); glTexCoord2f (0, 0); glVertex2f (wx + width + off, wy); glTexCoord2f (0, 1); glVertex2f (wx + width + off, wy - off); glTexCoord2f (0, 0); glVertex2f (wx - off, wy + height); glTexCoord2f (0, 1); glVertex2f (wx - off, wy + height + off); glTexCoord2f (1, 1); glVertex2f (wx, wy + height + off); glTexCoord2f (1, 0); glVertex2f (wx, wy + height); glTexCoord2f (1, 0); glVertex2f (wx + width, wy + height); glTexCoord2f (1, 1); glVertex2f (wx + width, wy + height + off); glTexCoord2f (0, 1); glVertex2f (wx + width + off, wy + height + off); glTexCoord2f (0, 0); glVertex2f (wx + width + off, wy + height); glTexCoord2f (1, 1); glVertex2f (wx, wy - off); glTexCoord2f (1, 0); glVertex2f (wx, wy); glTexCoord2f (1, 0); glVertex2f (wx + width, wy); glTexCoord2f (1, 1); glVertex2f (wx + width, wy - off); glTexCoord2f (1, 0); glVertex2f (wx, wy + height); glTexCoord2f (1, 1); glVertex2f (wx, wy + height + off); glTexCoord2f (1, 1); glVertex2f (wx + width, wy + height + off); glTexCoord2f (1, 0); glVertex2f (wx + width, wy + height); glTexCoord2f (0, 0); glVertex2f (wx - off, wy); glTexCoord2f (0, 0); glVertex2f (wx - off, wy + height); glTexCoord2f (1, 0); glVertex2f (wx, wy + height); glTexCoord2f (1, 0); glVertex2f (wx, wy); glTexCoord2f (1, 0); glVertex2f (wx + width, wy); glTexCoord2f (1, 0); glVertex2f (wx + width, wy + height); glTexCoord2f (0, 0); glVertex2f (wx + width + off, wy + height); glTexCoord2f (0, 0); glVertex2f (wx + width + off, wy); glEnd (); if (option_window_like->b) { disableTexture (s, &ts->windowTexture); } else { disableTexture (s, &ts->glowTexture); } glColor4usv (defaultColor); glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); if (t->textData) { float ox = 0.0; if (t->textData->width < width) ox = (width - (int)t->textData->width) / 2.0; textDrawText (s, t->textData, wx + ox, wy + height, t->opacity); } glEnableClientState (GL_TEXTURE_COORD_ARRAY); glDisable (GL_BLEND); screenTexEnvMode (s, GL_REPLACE); glColor4usv (defaultColor); sAttrib.opacity *= t->opacity; sAttrib.yScale = t->scale; sAttrib.xScale = t->scale; sAttrib.xTranslate = wx - w->attrib.x + w->input.left * sAttrib.xScale; sAttrib.yTranslate = wy - w->attrib.y + w->input.top * sAttrib.yScale; const BananaValue * option_mipmap = bananaGetOption (bananaIndex, "mipmap", s->screenNum); if (option_mipmap->b) display.textureFilter = GL_LINEAR_MIPMAP_LINEAR; initFragmentAttrib (&fragment, &sAttrib); matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f); matrixScale (&wTransform, sAttrib.xScale, sAttrib.yScale, 1.0f); matrixTranslate (&wTransform, sAttrib.xTranslate / sAttrib.xScale - w->attrib.x, sAttrib.yTranslate / sAttrib.yScale - w->attrib.y, 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*s->drawWindow) (w, &wTransform, &fragment, &infiniteRegion, mask); glPopMatrix (); display.textureFilter = filter; } s->addWindowGeometry = oldAddWindowGeometry; }
Matrix Matrix::matrixInvert(Matrix *matrix) { Matrix result; float matrix3x3[9]; /* Find the cofactor of each element. */ /* Element (i, j) (1, 1) */ matrix3x3[0] = matrix->elements[ 5]; matrix3x3[1] = matrix->elements[ 6]; matrix3x3[2] = matrix->elements[ 7]; matrix3x3[3] = matrix->elements[ 9]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[0] = matrixDeterminant(matrix3x3); /* Element (i, j) (1, 2) */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 9]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[4] = -matrixDeterminant(matrix3x3); /* Element (i, j) (1, 3) */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 5]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[13]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[8] = matrixDeterminant(matrix3x3); /* Element (i, j) (1, 4) */ matrix3x3[0] = matrix->elements[ 1]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 5]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[ 9]; matrix3x3[7] = matrix->elements[10]; matrix3x3[8] = matrix->elements[11]; result.elements[12] = -matrixDeterminant(matrix3x3); /* Element (i, j) (2, 1) */ matrix3x3[0] = matrix->elements[ 4]; matrix3x3[1] = matrix->elements[ 6]; matrix3x3[2] = matrix->elements[ 7]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[1] = -matrixDeterminant(matrix3x3); /* Element (i, j) (2, 2) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[10]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[5] = matrixDeterminant(matrix3x3); /* Element (i, j) (2, 3) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[14]; matrix3x3[8] = matrix->elements[15]; result.elements[9] = -matrixDeterminant(matrix3x3); /* Element (i, j) (2, 4) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 2]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 6]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[ 8]; matrix3x3[7] = matrix->elements[10]; matrix3x3[8] = matrix->elements[11]; result.elements[13] = matrixDeterminant(matrix3x3); /* Element (i, j) (3, 1) */ matrix3x3[0] = matrix->elements[ 4]; matrix3x3[1] = matrix->elements[ 5]; matrix3x3[2] = matrix->elements[ 7]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[15]; result.elements[2] = matrixDeterminant(matrix3x3); /* Element (i, j) (3, 2) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[11]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[15]; result.elements[6] = -matrixDeterminant(matrix3x3); /* Element (i, j) (3, 3) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[15]; result.elements[10] = matrixDeterminant(matrix3x3); /* Element (i, j) (3, 4) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 3]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 7]; matrix3x3[6] = matrix->elements[ 8]; matrix3x3[7] = matrix->elements[ 9]; matrix3x3[8] = matrix->elements[11]; result.elements[14] = -matrixDeterminant(matrix3x3); /* Element (i, j) (4, 1) */ matrix3x3[0] = matrix->elements[ 4]; matrix3x3[1] = matrix->elements[ 5]; matrix3x3[2] = matrix->elements[ 6]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[10]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[14]; result.elements[3] = -matrixDeterminant(matrix3x3); /* Element (i, j) (4, 2) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 2]; matrix3x3[3] = matrix->elements[ 8]; matrix3x3[4] = matrix->elements[ 9]; matrix3x3[5] = matrix->elements[10]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[14]; result.elements[7] = matrixDeterminant(matrix3x3); /* Element (i, j) (4, 3) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 2]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 6]; matrix3x3[6] = matrix->elements[12]; matrix3x3[7] = matrix->elements[13]; matrix3x3[8] = matrix->elements[14]; result.elements[11] = -matrixDeterminant(matrix3x3); /* Element (i, j) (4, 4) */ matrix3x3[0] = matrix->elements[ 0]; matrix3x3[1] = matrix->elements[ 1]; matrix3x3[2] = matrix->elements[ 2]; matrix3x3[3] = matrix->elements[ 4]; matrix3x3[4] = matrix->elements[ 5]; matrix3x3[5] = matrix->elements[ 6]; matrix3x3[6] = matrix->elements[ 8]; matrix3x3[7] = matrix->elements[ 9]; matrix3x3[8] = matrix->elements[10]; result.elements[15] = matrixDeterminant(matrix3x3); /* The adjoint is the transpose of the cofactor matrix. */ matrixTranspose(&result); /* The inverse is the adjoint divided by the determinant. */ result = matrixScale(&result, 1.0f / matrixDeterminant(matrix)); return result; }
static void scalePaintDecoration (CompWindow *w, const WindowPaintAttrib *attrib, const CompTransform *transform, Region region, unsigned int mask) { CompScreen *s = w->screen; SCALE_SCREEN (s); if (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i != SCALE_ICON_NONE) { WindowPaintAttrib sAttrib = *attrib; CompIcon *icon; SCALE_WINDOW (w); icon = getWindowIcon (w, 96, 96); if (!icon) icon = w->screen->defaultIcon; if (icon && (icon->texture.name || iconToTexture (w->screen, icon))) { REGION iconReg; float scale; float x, y; int width, height; int scaledWinWidth, scaledWinHeight; float ds; scaledWinWidth = w->width * sw->scale; scaledWinHeight = w->height * sw->scale; switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) { case SCALE_ICON_NONE: case SCALE_ICON_EMBLEM: scale = 1.0f; break; case SCALE_ICON_BIG: default: sAttrib.opacity /= 3; scale = MIN (((float) scaledWinWidth / icon->width), ((float) scaledWinHeight / icon->height)); break; } width = icon->width * scale; height = icon->height * scale; switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) { case SCALE_ICON_NONE: case SCALE_ICON_EMBLEM: x = w->attrib.x + scaledWinWidth - icon->width; y = w->attrib.y + scaledWinHeight - icon->height; break; case SCALE_ICON_BIG: default: x = w->attrib.x + scaledWinWidth / 2 - width / 2; y = w->attrib.y + scaledWinHeight / 2 - height / 2; break; } x += sw->tx; y += sw->ty; if (sw->slot) { sw->delta = fabs (sw->slot->x1 - w->attrib.x) + fabs (sw->slot->y1 - w->attrib.y) + fabs (1.0f - sw->slot->scale) * 500.0f; } if (sw->delta) { float o; ds = fabs (sw->tx) + fabs (sw->ty) + fabs (1.0f - sw->scale) * 500.0f; if (ds > sw->delta) ds = sw->delta; o = ds / sw->delta; if (sw->slot) { if (o < sw->lastThumbOpacity) o = sw->lastThumbOpacity; } else { if (o > sw->lastThumbOpacity) o = 0.0f; } sw->lastThumbOpacity = o; sAttrib.opacity = sAttrib.opacity * o; } mask |= PAINT_WINDOW_BLEND_MASK; iconReg.rects = &iconReg.extents; iconReg.numRects = 1; iconReg.extents.x1 = 0; iconReg.extents.y1 = 0; iconReg.extents.x2 = iconReg.extents.x1 + width; iconReg.extents.y2 = iconReg.extents.y1 + height; w->vCount = w->indexCount = 0; if (iconReg.extents.x1 < iconReg.extents.x2 && iconReg.extents.y1 < iconReg.extents.y2) (*w->screen->addWindowGeometry) (w, &icon->texture.matrix, 1, &iconReg, &iconReg); if (w->vCount) { FragmentAttrib fragment; CompTransform wTransform = *transform; initFragmentAttrib (&fragment, &sAttrib); matrixScale (&wTransform, scale, scale, 1.0f); matrixTranslate (&wTransform, x / scale, y / scale, 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*w->screen->drawWindowTexture) (w, &icon->texture, &fragment, mask); glPopMatrix (); } } } }
// QR Factorization void QR(double* A, int m, int n, double* Q, double* R) { // Not a very efficient approach, but simple and effective // Written by Nico van Duijn, 9/13/2015 // Source of algorithm (adjusted by me): // http://www.keithlantz.net/2012/05/qr-decomposition-using-householder-transformations/ // A is the (m*n) matrix to be factorized A=Q*R double mag, alpha; double u[m], v[m], vtrans[m]; double P[m * m], I[m * m], vvtrans[m * m], Rbackup[m * m], Qbackup[m * m]; matrixCopy(A, m, m, R); // Initialize R to A // Initialize Q, P, I to Identity for (int i = 0; i < m * m; i++)Q[i] = 0; for (int i = 0; i < m; i++)Q[i * n + i] = 1; for (int i = 0; i < m * m; i++)P[i] = 0; for (int i = 0; i < m; i++)P[i * n + i] = 1; for (int i = 0; i < m * m; i++)I[i] = 0; for (int i = 0; i < m; i++)I[i * n + i] = 1; for (int i = 0; i < n; i++) //loop through all columns { for (int q = 0; q < m; q++)u[q] = 0; // set u and v to zero for (int q = 0; q < m; q++)v[q] = 0; mag = 0.0; //set mag to zero for (int j = i; j < m; j++) { u[j] = R[j * n + i]; mag += u[j] * u[j]; } mag = sqrt(mag); alpha = u[i] < 0 ? mag : -mag; mag = 0.0; for (int j = i; j < m; j++) { v[j] = j == i ? u[j] + alpha : u[j]; mag += v[j] * v[j]; } mag = sqrt(mag); if (mag < 0.0000000001) continue; for (int j = i; j < m; j++) v[j] /= mag; // P = I - (v * v.transpose()) * 2.0; matrixTranspose(v, m, 1, vtrans); matrixMult(v, vtrans, m, 1, m, vvtrans); matrixScale(vvtrans, m, m, 2.0); matrixSub(I, vvtrans, m, m, P); // R = P * R; matrixMult(P, R, m, m, m, Rbackup); matrixCopy(Rbackup, m, m, R); //Q = Q * P; matrixMult(Q, P, m, m, m, Qbackup); matrixCopy(Qbackup, m, m, Q); } }
static Bool zoomPaintOutput(CompScreen *s, const ScreenPaintAttrib *sAttrib, const CompTransform *transform, Region region, CompOutput *output, unsigned int mask) { CompTransform zTransform = *transform; Bool status; ZOOM_SCREEN(s); if (output->id != ~0 && (zs->zoomed & (1 << output->id))) { int saveFilter; ZoomBox box; float scale, x, y, x1, y1; float oWidth = output->width; float oHeight = output->height; mask &= ~PAINT_SCREEN_REGION_MASK; zoomGetCurrentZoom(s, output->id, &box); x1 = box.x1 - output->region.extents.x1; y1 = box.y1 - output->region.extents.y1; scale = oWidth / (box.x2 - box.x1); x = ((oWidth / 2.0f) - x1) / oWidth; y = ((oHeight / 2.0f) - y1) / oHeight; x = 0.5f - x * scale; y = 0.5f - y * scale; matrixTranslate(&zTransform, -x, y, 0.0f); matrixScale(&zTransform, scale, scale, 1.0f); mask |= PAINT_SCREEN_TRANSFORMED_MASK; saveFilter = s->filter[SCREEN_TRANS_FILTER]; if ((zs->zoomOutput != output->id || !zs->adjust) && scale > 3.9f && !zs->opt[ZOOM_SCREEN_OPTION_FILTER_LINEAR].value.b) s->filter[SCREEN_TRANS_FILTER] = COMP_TEXTURE_FILTER_FAST; UNWRAP(zs, s, paintOutput); status = (*s->paintOutput)(s, sAttrib, &zTransform, region, output, mask); WRAP(zs, s, paintOutput, zoomPaintOutput); s->filter[SCREEN_TRANS_FILTER] = saveFilter; } else { UNWRAP(zs, s, paintOutput); status = (*s->paintOutput)(s, sAttrib, transform, region, output, mask); WRAP(zs, s, paintOutput, zoomPaintOutput); } if (status && zs->grab) { int x1, x2, y1, y2; x1 = MIN(zs->x1, zs->x2); y1 = MIN(zs->y1, zs->y2); x2 = MAX(zs->x1, zs->x2); y2 = MAX(zs->y1, zs->y2); if (zs->grabIndex) { transformToScreenSpace(s, output, -DEFAULT_Z_CAMERA, &zTransform); glPushMatrix(); glLoadMatrixf(zTransform.m); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glColor4us(0x2fff, 0x2fff, 0x4fff, 0x4fff); glRecti(x1, y2, x2, y1); glColor4us(0x2fff, 0x2fff, 0x4fff, 0x9fff); glBegin(GL_LINE_LOOP); glVertex2i(x1, y1); glVertex2i(x2, y1); glVertex2i(x2, y2); glVertex2i(x1, y2); glEnd(); glColor4usv(defaultColor); glDisable(GL_BLEND); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glPopMatrix(); } } return status; }
/* * groupPaintWindow * */ Bool groupPaintWindow (CompWindow *w, const WindowPaintAttrib *attrib, const CompTransform *transform, Region region, unsigned int mask) { Bool status; Bool doRotate, doTabbing, showTabbar; CompScreen *s = w->screen; GROUP_SCREEN (s); GROUP_WINDOW (w); if (gw->group) { GroupSelection *group = gw->group; doRotate = (group->changeState != NoTabChange) && HAS_TOP_WIN (group) && HAS_PREV_TOP_WIN (group) && (IS_TOP_TAB (w, group) || IS_PREV_TOP_TAB (w, group)); doTabbing = (gw->animateState & (IS_ANIMATED | FINISHED_ANIMATION)) && !(IS_TOP_TAB (w, group) && (group->tabbingState == Tabbing)); showTabbar = group->tabBar && (group->tabBar->state != PaintOff) && (((IS_TOP_TAB (w, group)) && ((group->changeState == NoTabChange) || (group->changeState == TabChangeNewIn))) || (IS_PREV_TOP_TAB (w, group) && (group->changeState == TabChangeOldOut))); } else { doRotate = FALSE; doTabbing = FALSE; showTabbar = FALSE; } if (gw->windowHideInfo) mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK; if (gw->inSelection || gw->resizeGeometry || doRotate || doTabbing || showTabbar) { WindowPaintAttrib wAttrib = *attrib; CompTransform wTransform = *transform; float animProgress = 0.0f; int drawnPosX = 0, drawnPosY = 0; if (gw->inSelection) { const BananaValue * option_select_opacity = bananaGetOption (bananaIndex, "select_opacity", s->screenNum); const BananaValue * option_select_saturation = bananaGetOption (bananaIndex, "select_saturation", s->screenNum); const BananaValue * option_select_brightness = bananaGetOption (bananaIndex, "select_brightness", s->screenNum); wAttrib.opacity = OPAQUE * option_select_opacity->i / 100; wAttrib.saturation = COLOR * option_select_saturation->i / 100; wAttrib.brightness = BRIGHT * option_select_brightness->i / 100; } if (doTabbing) { /* fade the window out */ float progress; int distanceX, distanceY; float origDistance, distance; if (gw->animateState & FINISHED_ANIMATION) { drawnPosX = gw->destination.x; drawnPosY = gw->destination.y; } else { drawnPosX = gw->orgPos.x + gw->tx; drawnPosY = gw->orgPos.y + gw->ty; } distanceX = drawnPosX - gw->destination.x; distanceY = drawnPosY - gw->destination.y; distance = sqrt (pow (distanceX, 2) + pow (distanceY, 2)); distanceX = (gw->orgPos.x - gw->destination.x); distanceY = (gw->orgPos.y - gw->destination.y); origDistance = sqrt (pow (distanceX, 2) + pow (distanceY, 2)); if (!distanceX && !distanceY) progress = 1.0f; else progress = 1.0f - (distance / origDistance); animProgress = progress; progress = MAX (progress, 0.0f); if (gw->group->tabbingState == Tabbing) progress = 1.0f - progress; wAttrib.opacity = (float)wAttrib.opacity * progress; } if (doRotate) { const BananaValue * option_change_animation_time = bananaGetOption (bananaIndex, "change_animation_time", s->screenNum); float timeLeft = gw->group->changeAnimationTime; int animTime = option_change_animation_time->f * 500; if (gw->group->changeState == TabChangeOldOut) timeLeft += animTime; /* 0 at the beginning, 1 at the end */ animProgress = 1 - (timeLeft / (2 * animTime)); } if (gw->resizeGeometry) { int xOrigin, yOrigin; float xScale, yScale; BoxRec box; groupGetStretchRectangle (w, &box, &xScale, &yScale); xOrigin = w->attrib.x - w->input.left; yOrigin = w->attrib.y - w->input.top; matrixTranslate (&wTransform, xOrigin, yOrigin, 0.0f); matrixScale (&wTransform, xScale, yScale, 1.0f); matrixTranslate (&wTransform, (gw->resizeGeometry->x - w->attrib.x) / xScale - xOrigin, (gw->resizeGeometry->y - w->attrib.y) / yScale - yOrigin, 0.0f); mask |= PAINT_WINDOW_TRANSFORMED_MASK; } else if (doRotate || doTabbing) { float animWidth, animHeight; float animScaleX, animScaleY; CompWindow *morphBase, *morphTarget; if (doTabbing) { if (gw->group->tabbingState == Tabbing) { morphBase = w; morphTarget = TOP_TAB (gw->group); } else { morphTarget = w; if (HAS_TOP_WIN (gw->group)) morphBase = TOP_TAB (gw->group); else morphBase = gw->group->lastTopTab; } } else { morphBase = PREV_TOP_TAB (gw->group); morphTarget = TOP_TAB (gw->group); } animWidth = (1 - animProgress) * WIN_REAL_WIDTH (morphBase) + animProgress * WIN_REAL_WIDTH (morphTarget); animHeight = (1 - animProgress) * WIN_REAL_HEIGHT (morphBase) + animProgress * WIN_REAL_HEIGHT (morphTarget); animWidth = MAX (1.0f, animWidth); animHeight = MAX (1.0f, animHeight); animScaleX = animWidth / WIN_REAL_WIDTH (w); animScaleY = animHeight / WIN_REAL_HEIGHT (w); if (doRotate) matrixScale (&wTransform, 1.0f, 1.0f, 1.0f / s->width); matrixTranslate (&wTransform, WIN_REAL_X (w) + WIN_REAL_WIDTH (w) / 2.0f, WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) / 2.0f, 0.0f); if (doRotate) { float rotateAngle = animProgress * 180.0f; if (IS_TOP_TAB (w, gw->group)) rotateAngle += 180.0f; if (gw->group->changeAnimationDirection < 0) rotateAngle *= -1.0f; matrixRotate (&wTransform, rotateAngle, 0.0f, 1.0f, 0.0f); } if (doTabbing) matrixTranslate (&wTransform, drawnPosX - WIN_X (w), drawnPosY - WIN_Y (w), 0.0f); matrixScale (&wTransform, animScaleX, animScaleY, 1.0f); matrixTranslate (&wTransform, -(WIN_REAL_X (w) + WIN_REAL_WIDTH (w) / 2.0f), -(WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) / 2.0f), 0.0f); mask |= PAINT_WINDOW_TRANSFORMED_MASK; } UNWRAP (gs, s, paintWindow); status = (*s->paintWindow)(w, &wAttrib, &wTransform, region, mask); if (showTabbar) groupPaintTabBar (gw->group, &wAttrib, &wTransform, mask, region); WRAP (gs, s, paintWindow, groupPaintWindow); } else { UNWRAP (gs, s, paintWindow); status = (*s->paintWindow)(w, attrib, transform, region, mask); WRAP (gs, s, paintWindow, groupPaintWindow); } return status; }
static Bool clonePaintOutput(CompScreen * s, const ScreenPaintAttrib * sAttrib, const CompTransform * transform, Region region, CompOutput * outputPtr, unsigned int mask) { Bool status; int i, dst, output = 0; CLONE_SCREEN(s); dst = output = (outputPtr->id != ~0) ? outputPtr->id : 0; if (!cs->grab || cs->grabbedOutput != output) { for (i = 0; i < cs->nClone; i++) { if (cs->clone[i].dst == output) { region = cs->clone[i].region; dst = cs->clone[i].src; if (s->outputDev[dst].width != s->outputDev[output].width || s->outputDev[dst].height != s->outputDev[output].height) cs->transformed = TRUE; else cs->transformed = FALSE; break; } } } UNWRAP(cs, s, paintOutput); if (outputPtr->id != ~0) status = (*s->paintOutput) (s, sAttrib, transform, region, &s->outputDev[dst], mask); else status = (*s->paintOutput) (s, sAttrib, transform, region, outputPtr, mask); WRAP(cs, s, paintOutput, clonePaintOutput); if (cs->grab) { CompTransform sTransform = *transform; CompWindow *w; GLenum filter; float zoom1, zoom2x, zoom2y, x1, y1, x2, y2; float zoomX, zoomY; int dx, dy; zoom1 = 160.0f / s->outputDev[cs->src].height; x1 = cs->x - (s->outputDev[cs->src].region.extents.x1 * zoom1); y1 = cs->y - (s->outputDev[cs->src].region.extents.y1 * zoom1); x1 -= (s->outputDev[cs->src].width * zoom1) / 2; y1 -= (s->outputDev[cs->src].height * zoom1) / 2; if (cs->grabIndex) { x2 = s->outputDev[cs->grabbedOutput].region.extents.x1 - s->outputDev[cs->src].region.extents.x1; y2 = s->outputDev[cs->grabbedOutput].region.extents.y1 - s->outputDev[cs->src].region.extents.y1; zoom2x = (float)s->outputDev[cs->grabbedOutput].width / s->outputDev[cs->src].width; zoom2y = (float)s->outputDev[cs->grabbedOutput].height / s->outputDev[cs->src].height; } else { x2 = s->outputDev[cs->dst].region.extents.x1 - s->outputDev[cs->src].region.extents.x1; y2 = s->outputDev[cs->dst].region.extents.y1 - s->outputDev[cs->src].region.extents.y1; zoom2x = (float)s->outputDev[cs->dst].width / s->outputDev[cs->src].width; zoom2y = (float)s->outputDev[cs->dst].height / s->outputDev[cs->src].height; } /* XXX: hmm.. why do I need this.. */ if (x2 < 0.0f) x2 *= zoom2x; if (y2 < 0.0f) y2 *= zoom2y; dx = x1 * (1.0f - cs->offset) + x2 * cs->offset; dy = y1 * (1.0f - cs->offset) + y2 * cs->offset; zoomX = zoom1 * (1.0f - cs->offset) + zoom2x * cs->offset; zoomY = zoom1 * (1.0f - cs->offset) + zoom2y * cs->offset; matrixTranslate(&sTransform, -0.5f, -0.5f, -DEFAULT_Z_CAMERA); matrixScale(&sTransform, 1.0f / s->outputDev[output].width, -1.0f / s->outputDev[output].height, 1.0f); matrixTranslate(&sTransform, dx - s->outputDev[output].region.extents.x1, dy - s->outputDev[output].region.extents.y2, 0.0f); matrixScale(&sTransform, zoomX, zoomY, 1.0f); glPushMatrix(); glLoadMatrixf(sTransform.m); filter = s->display->textureFilter; if (cs->offset == 0.0f) s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR; for (w = s->windows; w; w = w->next) { if (w->destroyed) continue; if (!w->shaded) { if (w->attrib.map_state != IsViewable || !w->damaged) continue; } (*s->paintWindow) (w, &w->paint, &sTransform, &s->outputDev[cs->src].region, PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK); } s->display->textureFilter = filter; glPopMatrix(); } return status; }
/* * groupPaintTabBar * */ static void groupPaintTabBar (GroupSelection *group, const WindowPaintAttrib *wAttrib, const CompTransform *transform, unsigned int mask, Region clipRegion) { CompWindow *topTab; CompScreen *s = group->screen; GroupTabBar *bar = group->tabBar; int count; REGION box; GROUP_SCREEN (s); if (HAS_TOP_WIN (group)) topTab = TOP_TAB (group); else topTab = PREV_TOP_TAB (group); #define PAINT_BG 0 #define PAINT_SEL 1 #define PAINT_THUMBS 2 #define PAINT_TEXT 3 #define PAINT_MAX 4 box.rects = &box.extents; box.numRects = 1; const BananaValue * option_fade_time = bananaGetOption (bananaIndex, "fade_time", s->screenNum); const BananaValue * option_mipmaps = bananaGetOption (bananaIndex, "mipmaps", s->screenNum); const BananaValue * option_fade_text_time = bananaGetOption (bananaIndex, "fade_text_time", s->screenNum); for (count = 0; count < PAINT_MAX; count++) { int alpha = OPAQUE; float wScale = 1.0f, hScale = 1.0f; GroupCairoLayer *layer = NULL; if (bar->state == PaintFadeIn) alpha -= alpha * bar->animationTime / (option_fade_time->f * 1000); else if (bar->state == PaintFadeOut) alpha = alpha * bar->animationTime / (option_fade_time->f * 1000); switch (count) { case PAINT_BG: { int newWidth; layer = bar->bgLayer; /* handle the repaint of the background */ newWidth = bar->region->extents.x2 - bar->region->extents.x1; if (layer && (newWidth > layer->texWidth)) newWidth = layer->texWidth; wScale = (double) (bar->region->extents.x2 - bar->region->extents.x1) / (double) newWidth; /* FIXME: maybe move this over to groupResizeTabBarRegion - the only problem is that we would have 2 redraws if there is an animation */ if (newWidth != bar->oldWidth || bar->bgAnimation) groupRenderTabBarBackground (group); bar->oldWidth = newWidth; box.extents = bar->region->extents; } break; case PAINT_SEL: if (group->topTab != gs->draggedSlot) { layer = bar->selectionLayer; box.extents = group->topTab->region->extents; } break; case PAINT_THUMBS: { GLenum oldTextureFilter; GroupTabBarSlot *slot; oldTextureFilter = display.textureFilter; if (option_mipmaps->b) display.textureFilter = GL_LINEAR_MIPMAP_LINEAR; for (slot = bar->slots; slot; slot = slot->next) { if (slot != gs->draggedSlot || !gs->dragged) groupPaintThumb (group, slot, transform, wAttrib->opacity); } display.textureFilter = oldTextureFilter; } break; case PAINT_TEXT: if (bar->textLayer && (bar->textLayer->state != PaintOff)) { layer = bar->textLayer; box.extents.x1 = bar->region->extents.x1 + 5; box.extents.x2 = bar->region->extents.x1 + bar->textLayer->texWidth + 5; box.extents.y1 = bar->region->extents.y2 - bar->textLayer->texHeight - 5; box.extents.y2 = bar->region->extents.y2 - 5; if (box.extents.x2 > bar->region->extents.x2) box.extents.x2 = bar->region->extents.x2; /* recalculate the alpha again for text fade... */ if (layer->state == PaintFadeIn) alpha -= alpha * layer->animationTime / (option_fade_text_time->f * 1000); else if (layer->state == PaintFadeOut) alpha = alpha * layer->animationTime / (option_fade_text_time->f * 1000); } break; } if (layer) { CompMatrix matrix = layer->texture.matrix; /* remove the old x1 and y1 so we have a relative value */ box.extents.x2 -= box.extents.x1; box.extents.y2 -= box.extents.y1; box.extents.x1 = (box.extents.x1 - topTab->attrib.x) / wScale + topTab->attrib.x; box.extents.y1 = (box.extents.y1 - topTab->attrib.y) / hScale + topTab->attrib.y; /* now add the new x1 and y1 so we have a absolute value again, also we don't want to stretch the texture... */ if (box.extents.x2 * wScale < layer->texWidth) box.extents.x2 += box.extents.x1; else box.extents.x2 = box.extents.x1 + layer->texWidth; if (box.extents.y2 * hScale < layer->texHeight) box.extents.y2 += box.extents.y1; else box.extents.y2 = box.extents.y1 + layer->texHeight; matrix.x0 -= box.extents.x1 * matrix.xx; matrix.y0 -= box.extents.y1 * matrix.yy; topTab->vCount = topTab->indexCount = 0; addWindowGeometry (topTab, &matrix, 1, &box, clipRegion); if (topTab->vCount) { FragmentAttrib fragment; CompTransform wTransform = *transform; matrixTranslate (&wTransform, WIN_X (topTab), WIN_Y (topTab), 0.0f); matrixScale (&wTransform, wScale, hScale, 1.0f); matrixTranslate (&wTransform, wAttrib->xTranslate / wScale - WIN_X (topTab), wAttrib->yTranslate / hScale - WIN_Y (topTab), 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); alpha = alpha * ((float)wAttrib->opacity / OPAQUE); initFragmentAttrib (&fragment, wAttrib); fragment.opacity = alpha; (*s->drawWindowTexture)(topTab, &layer->texture, &fragment, mask | PAINT_WINDOW_BLEND_MASK | PAINT_WINDOW_TRANSFORMED_MASK | PAINT_WINDOW_TRANSLUCENT_MASK); glPopMatrix (); } } } }
static Bool ringPaintWindow (CompWindow *w, const WindowPaintAttrib *attrib, const CompTransform *transform, Region region, unsigned int mask) { CompScreen *s = w->screen; Bool status; RING_SCREEN (s); if (rs->state != RingStateNone) { WindowPaintAttrib sAttrib = *attrib; Bool scaled = FALSE; RING_WINDOW (w); if (w->mapNum) { if (!w->texture->pixmap && !w->bindFailed) bindWindow (w); } if (rw->adjust || rw->slot) { scaled = rw->adjust || (rw->slot && rs->paintingSwitcher); mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK; } else if (rs->state != RingStateIn) { if (ringGetDarkenBack (s)) { /* modify brightness of the other windows */ sAttrib.brightness = sAttrib.brightness / 2; } } UNWRAP (rs, s, paintWindow); status = (*s->paintWindow) (w, &sAttrib, transform, region, mask); WRAP (rs, s, paintWindow, ringPaintWindow); if (scaled && w->texture->pixmap) { FragmentAttrib fragment; CompTransform wTransform = *transform; if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) return FALSE; initFragmentAttrib (&fragment, &w->lastPaint); if (rw->slot) { fragment.brightness = (float) fragment.brightness * rw->slot->depthBrightness; if (w != rs->selectedWindow) fragment.opacity = (float)fragment.opacity * ringGetInactiveOpacity (s) / 100; } if (w->alpha || fragment.opacity != OPAQUE) mask |= PAINT_WINDOW_TRANSLUCENT_MASK; matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f); matrixScale (&wTransform, rw->scale, rw->scale, 1.0f); matrixTranslate (&wTransform, rw->tx / rw->scale - w->attrib.x, rw->ty / rw->scale - w->attrib.y, 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*s->drawWindow) (w, &wTransform, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); glPopMatrix (); } if (scaled && (rs->state != RingStateIn) && ((ringGetOverlayIcon (s) != OverlayIconNone) || !w->texture->pixmap)) { CompIcon *icon; icon = getWindowIcon (w, MAX_ICON_SIZE, MAX_ICON_SIZE); if (!icon) icon = w->screen->defaultIcon; if (icon && (icon->texture.name || iconToTexture (w->screen, icon))) { REGION iconReg; CompMatrix matrix; float scale; float x, y; int width, height; int scaledWinWidth, scaledWinHeight; RingOverlayIconEnum iconOverlay; scaledWinWidth = w->attrib.width * rw->scale; scaledWinHeight = w->attrib.height * rw->scale; if (!w->texture->pixmap) iconOverlay = OverlayIconBig; else iconOverlay = ringGetOverlayIcon (s); switch (iconOverlay) { case OverlayIconNone: case OverlayIconEmblem: scale = (rw->slot) ? rw->slot->depthScale : 1.0f; scale = MIN ((scale * ICON_SIZE / icon->width), (scale * ICON_SIZE / icon->height)); break; case OverlayIconBig: default: if (w->texture->pixmap) { /* only change opacity if not painting an icon for a minimized window */ sAttrib.opacity /= 3; scale = MIN (((float) scaledWinWidth / icon->width), ((float) scaledWinHeight / icon->height)); } else { scale = 0.8f * ((rw->slot) ? rw->slot->depthScale : 1.0f); scale = MIN ((scale * ringGetThumbWidth (s) / icon->width), (scale * ringGetThumbHeight (s) / icon->height)); } break; } width = icon->width * scale; height = icon->height * scale; switch (iconOverlay) { case OverlayIconNone: case OverlayIconEmblem: x = w->attrib.x + scaledWinWidth - width; y = w->attrib.y + scaledWinHeight - height; break; case OverlayIconBig: default: x = w->attrib.x + scaledWinWidth / 2 - width / 2; y = w->attrib.y + scaledWinHeight / 2 - height / 2; break; } x += rw->tx; y += rw->ty; mask |= PAINT_WINDOW_BLEND_MASK | PAINT_WINDOW_TRANSFORMED_MASK; iconReg.rects = &iconReg.extents; iconReg.numRects = 1; iconReg.extents.x1 = w->attrib.x; iconReg.extents.y1 = w->attrib.y; iconReg.extents.x2 = w->attrib.x + icon->width; iconReg.extents.y2 = w->attrib.y + icon->height; matrix = icon->texture.matrix; matrix.x0 -= (w->attrib.x * icon->texture.matrix.xx); matrix.y0 -= (w->attrib.y * icon->texture.matrix.yy); w->vCount = w->indexCount = 0; (*w->screen->addWindowGeometry) (w, &matrix, 1, &iconReg, &infiniteRegion); if (w->vCount) { FragmentAttrib fragment; CompTransform wTransform = *transform; if (!w->texture->pixmap) sAttrib.opacity = w->paint.opacity; initFragmentAttrib (&fragment, &sAttrib); if (rw->slot) fragment.brightness = (float) fragment.brightness * rw->slot->depthBrightness; matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f); matrixScale (&wTransform, scale, scale, 1.0f); matrixTranslate (&wTransform, (x - w->attrib.x) / scale - w->attrib.x, (y - w->attrib.y) / scale - w->attrib.y, 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*w->screen->drawWindowTexture) (w, &icon->texture, &fragment, mask); glPopMatrix (); } } } } else { UNWRAP (rs, s, paintWindow); status = (*s->paintWindow) (w, attrib, transform, region, mask); WRAP (rs, s, paintWindow, ringPaintWindow); } return status; }
/* * groupPaintThumb - taken from switcher and modified for tab bar * */ static void groupPaintThumb (GroupSelection *group, GroupTabBarSlot *slot, const CompTransform *transform, int targetOpacity) { CompWindow *w = slot->window; CompScreen *s = w->screen; AddWindowGeometryProc oldAddWindowGeometry; WindowPaintAttrib wAttrib = w->paint; int tw, th; tw = slot->region->extents.x2 - slot->region->extents.x1; th = slot->region->extents.y2 - slot->region->extents.y1; /* Wrap drawWindowGeometry to make sure the general drawWindowGeometry function is used */ oldAddWindowGeometry = s->addWindowGeometry; s->addWindowGeometry = addWindowGeometry; const BananaValue * option_fade_time = bananaGetOption (bananaIndex, "fade_time", s->screenNum); /* animate fade */ if (group && group->tabBar->state == PaintFadeIn) { wAttrib.opacity -= wAttrib.opacity * group->tabBar->animationTime / (option_fade_time->f * 1000); } else if (group && group->tabBar->state == PaintFadeOut) { wAttrib.opacity = wAttrib.opacity * group->tabBar->animationTime / (option_fade_time->f * 1000); } wAttrib.opacity = wAttrib.opacity * targetOpacity / OPAQUE; if (w->mapNum) { FragmentAttrib fragment; CompTransform wTransform = *transform; int width, height; int vx, vy; width = w->width + w->output.left + w->output.right; height = w->height + w->output.top + w->output.bottom; if (width > tw) wAttrib.xScale = (float) tw / width; else wAttrib.xScale = 1.0f; if (height > th) wAttrib.yScale = (float) tw / height; else wAttrib.yScale = 1.0f; if (wAttrib.xScale < wAttrib.yScale) wAttrib.yScale = wAttrib.xScale; else wAttrib.xScale = wAttrib.yScale; /* FIXME: do some more work on the highlight on hover feature // Highlight on hover if (group && group->tabBar && group->tabBar->hoveredSlot == slot) { wAttrib.saturation = 0; wAttrib.brightness /= 1.25f; }*/ groupGetDrawOffsetForSlot (slot, &vx, &vy); wAttrib.xTranslate = (slot->region->extents.x1 + slot->region->extents.x2) / 2 + vx; wAttrib.yTranslate = slot->region->extents.y1 + vy; initFragmentAttrib (&fragment, &wAttrib); matrixTranslate (&wTransform, wAttrib.xTranslate, wAttrib.yTranslate, 0.0f); matrixScale (&wTransform, wAttrib.xScale, wAttrib.yScale, 1.0f); matrixTranslate (&wTransform, -(WIN_X (w) + WIN_WIDTH (w) / 2), -(WIN_Y (w) - w->output.top), 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*s->drawWindow)(w, &wTransform, &fragment, &infiniteRegion, PAINT_WINDOW_TRANSFORMED_MASK | PAINT_WINDOW_TRANSLUCENT_MASK); glPopMatrix (); } s->addWindowGeometry = oldAddWindowGeometry; }
/* Calculate the inverse of a matrix */ void matrixInverse(struct Matrix *out, const struct Matrix a) { struct Matrix temp; matrixCofactor(&temp, a); matrixScale(out, temp, 1/matrixDeterminant(a)); }