/*
* Animation plugin for compiz/beryl
*
* airplane3d.c
*
* Copyright : (C) 2006 Erkin Bahceci
* E-mail : erkinbah@gmail.com
*
* Based on Wobbly and Minimize plugins by
* : David Reveman
* E-mail : davidr@novell.com>
*
* Airplane added by : Carlo Palma
* E-mail : carlopalma@salug.it
* Based on code originally written by Mark J. Kilgard
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "animation-internal.h"
// Divide the window in 8 polygons (6 quadrilaters and 2 triangles (all of them draw as quadrilaters))
// Based on tessellateIntoRectangles and tessellateIntoHexagons. Improperly called tessellation.
static Bool
tessellateIntoAirplane (CompWindow * w)
{
ANIM_WINDOW (w);
PolygonSet *pset = aw->polygonSet;
if (!pset)
return FALSE;
float winLimitsX; // boundaries of polygon tessellation
float winLimitsY;
float winLimitsW;
float winLimitsH;
winLimitsX = BORDER_X (w);
winLimitsY = BORDER_Y (w);
winLimitsW = BORDER_W (w);
winLimitsH = BORDER_H (w);
int numpol = 8;
if (pset->nPolygons != numpol)
{
if (pset->nPolygons > 0)
freePolygonObjects (pset);
pset->nPolygons = numpol;
pset->polygons = calloc (pset->nPolygons, sizeof (PolygonObject));
if (!pset->polygons)
{
compLogMessage (w->screen->display, "animation",
CompLogLevelError, "Not enough memory");
pset->nPolygons = 0;
return FALSE;
}
}
float thickness;
thickness = 1;
thickness /= w->screen->width;
pset->thickness = thickness;
pset->nTotalFrontVertices = 0;
float W = (float)winLimitsW;
float H2 = (float)winLimitsH / 2;
float H3 = (float)winLimitsH / 3;
float H6 = (float)winLimitsH / 6;
float halfThick = pset->thickness / 2;
/**
*
* These correspond to the polygons:
* based on GLUT sample origami.c code by Mark J. Kilgard
*
* |- W -|
* |- H2 -|
*
* - -- +----+--------+------------------+
* | | | / |
* | | 6 / |
* | 7 | / 5 |
* H2 | | + |
* | +--------+------------------+
* | / 4 |
* H __ |/____________.__________________|
* |\ center |
* | \ 3 |
* | +--------+------------------+
* | | + |
* | 0 | \ |
* | | 1 \ 2 |
* | | | \ |
* - +----+--------+------------------+
*
*
*/
PolygonObject *p = pset->polygons;
int i;
for (i = 0; i < 8; i++, p++)
{
float topRightY, topLeftY, bottomLeftY, bottomRightY;
float topLeftX, topRightX, bottomLeftX, bottomRightX;
float n6, n7, n9, n10, n12, n13, n15, n16;
p->centerPos.x = p->centerPosStart.x = winLimitsX + H2;
p->centerPos.y = p->centerPosStart.y = winLimitsY + H2;
p->centerPos.z = p->centerPosStart.z = -halfThick;
p->rotAngle = p->rotAngleStart = 0;
p->nSides = 4;
p->nVertices = 2 * 4;
pset->nTotalFrontVertices += 4;
switch (i)
{
case 0:
topLeftX = -H2;
topLeftY = 0;
bottomLeftX = -H2;
bottomLeftY = H2;
bottomRightX = -H3;
bottomRightY = H2;
topRightX = -H3;
topRightY = H6;
n6 = -1;
n7 = 0;
n9 = 0;
n10 = 1;
n12 = 1;
n13 = 0;
n15 = 1 / sqrt (2);
n16 = 1 / sqrt (2);
break;
case 1:
topLeftX = -H3;
topLeftY = H6;
bottomLeftX = -H3;
bottomLeftY = H2;
bottomRightX = 0;
bottomRightY = H2;
topRightX = 0;
topRightY = H2;
n6 = -1;
n7 = 0;
n9 = 0;
n10 = 1;
n12 = 1 / sqrt (2);
n13 = 1 / sqrt (2);
n15 = 1 / sqrt (2);
n16 = 1 / sqrt (2);
break;
case 2:
topLeftX = -H3;
topLeftY = H6;
bottomLeftX = 0;
bottomLeftY = H2;
bottomRightX = W - H2;
bottomRightY = H2;
topRightX = W - H2;
topRightY = H6;
n6 = -1 / sqrt (2);
n7 = 1 / sqrt (2);
n9 = 0;
n10 = 1;
n12 = 1;
n13 = 0;
n15 = 0;
n16 = -1;
break;
case 3:
topLeftX = -H2;
topLeftY = 0;
bottomLeftX = -H3;
bottomLeftY = H6;
bottomRightX = W - H2;
bottomRightY = H6;
topRightX = W - H2;
topRightY = 0;
n6 = -1 / sqrt (2);
n7 = 1 / sqrt (2);
n9 = 0;
n10 = 1;
n12 = 1;
n13 = 0;
n15 = 0;
n16 = -1;
break;
case 4:
topLeftX = -H3;
topLeftY = -H6;
bottomLeftX = -H2;
bottomLeftY = 0;
bottomRightX = W - H2;
bottomRightY = 0;
topRightX = W - H2;
topRightY = -H6;
n6 = -1 / sqrt (2);
n7 = -1 / sqrt (2);
n9 = 0;
n10 = 1;
n12 = 1;
n13 = 0;
n15 = 0;
n16 = -1;
break;
case 5:
topLeftX = 0;
topLeftY = -H2;
bottomLeftX = -H3;
bottomLeftY = -H6;
bottomRightX = W - H2;
bottomRightY = -H6;
topRightX = W - H2;
topRightY = -H2;
n6 = -1 / sqrt (2);
n7 = -1 / sqrt (2);
n9 = 0;
n10 = 1;
n12 = 1;
n13 = 0;
n15 = 0;
n16 = -1;
break;
case 6:
topLeftX = -H3;
topLeftY = -H2;
bottomLeftX = -H3;
bottomLeftY = -H6;
bottomRightX = -H3;
bottomRightY = -H6;
topRightX = 0;
topRightY = -H2;
n6 = -1;
n7 = 0;
n9 = 1 / sqrt (2);
n10 = 1 / sqrt (2);
n12 = 1 / sqrt (2);
n13 = 1 / sqrt (2);
n15 = 0;
n16 = -1;
break;
default:
topLeftX = -H2;
topLeftY = -H2;
bottomLeftX = -H2;
bottomLeftY = 0;
bottomRightX = -H3;
bottomRightY = -H6;
topRightX = -H3;
topRightY = -H2;
n6 = -1;
n7 = 0;
n9 = 1 / sqrt (2);
n10 = 1 / sqrt (2);
n12 = 1;
n13 = 0;
n15 = 0;
n16 = -1;
break;
}
// 4 front, 4 back vertices
if (!p->vertices)
{
p->vertices = calloc (8 * 3, sizeof (GLfloat));
}
if (!p->vertices)
{
compLogMessage (w->screen->display, "animation",
CompLogLevelError, "Not enough memory");
freePolygonObjects (pset);
return FALSE;
}
GLfloat *pv = p->vertices;
// Determine 4 front vertices in ccw direction
pv[0] = topLeftX;
pv[1] = topLeftY;
pv[2] = halfThick;
pv[3] = bottomLeftX;
pv[4] = bottomLeftY;
pv[5] = halfThick;
pv[6] = bottomRightX;
pv[7] = bottomRightY;
pv[8] = halfThick;
pv[9] = topRightX;
pv[10] = topRightY;
pv[11] = halfThick;
// Determine 4 back vertices in cw direction
pv[12] = topRightX;
pv[13] = topRightY;
pv[14] = -halfThick;
pv[15] = bottomRightX;
pv[16] = bottomRightY;
pv[17] = -halfThick;
pv[18] = bottomLeftX;
pv[19] = bottomLeftY;
pv[20] = -halfThick;
pv[21] = topLeftX;
pv[22] = topLeftY;
pv[23] = -halfThick;
// 16 indices for 4 sides (for quad strip)
if (!p->sideIndices)
{
p->sideIndices = calloc (4 * 4, sizeof (GLushort));
}
if (!p->sideIndices)
{
compLogMessage (w->screen->display, "animation",
CompLogLevelError, "Not enough memory");
freePolygonObjects (pset);
return FALSE;
}
GLushort *ind = p->sideIndices;
int id = 0;
ind[id++] = 0;
ind[id++] = 7;
ind[id++] = 6;
ind[id++] = 1;
ind[id++] = 1;
ind[id++] = 6;
ind[id++] = 5;
ind[id++] = 2;
ind[id++] = 2;
ind[id++] = 5;
ind[id++] = 4;
ind[id++] = 3;
ind[id++] = 3;
ind[id++] = 4;
ind[id++] = 7;
ind[id++] = 0;
// Surface normals
if (!p->normals)
{
p->normals = calloc ((2 + 4) * 3, sizeof (GLfloat));
}
if (!p->normals)
{
compLogMessage (w->screen->display, "animation",
CompLogLevelError, "Not enough memory");
freePolygonObjects (pset);
return FALSE;
}
GLfloat *nor = p->normals;
// Front
nor[0] = 0;
nor[1] = 0;
nor[2] = -1;
// Back
nor[3] = 0;
nor[4] = 0;
nor[5] = 1;
// Sides
nor[6] = n6;
nor[7] = n7;
nor[8] = 0;
nor[9] = n9;
nor[10] = n10;
nor[11] = 0;
nor[12] = n12;
nor[13] = n13;
nor[14] = 0;
nor[15] = n15;
nor[16] = n16;
nor[17] = 0;
if (i < 4)
{
p->boundingBox.x1 = p->centerPos.x + topLeftX;
p->boundingBox.y1 = p->centerPos.y + topLeftY;
p->boundingBox.x2 = ceil (p->centerPos.x + bottomRightX);
p->boundingBox.y2 = ceil (p->centerPos.y + bottomRightY);
}
else
{
p->boundingBox.x1 = p->centerPos.x + bottomLeftX;
p->boundingBox.y1 = p->centerPos.y + topLeftY;
p->boundingBox.x2 = ceil (p->centerPos.x + bottomRightX);
p->boundingBox.y2 = ceil (p->centerPos.y + bottomLeftY);
}
}
return TRUE;
}
void
fxAirplane3DInit (CompScreen * s, CompWindow * w)
{
ANIM_SCREEN (s);
ANIM_WINDOW (w);
float airplanePathLength =
animGetF (as, aw, ANIM_SCREEN_OPTION_AIRPLANE_PATHLENGTH);
if (!tessellateIntoAirplane (w))
return;
PolygonSet *pset = aw->polygonSet;
PolygonObject *p = pset->polygons;
float winLimitsW; // boundaries of polygon tessellation
float winLimitsH;
winLimitsW = BORDER_W (w);
winLimitsH = BORDER_H (w);
float H4 = (float)winLimitsH / 4;
float H6 = (float)winLimitsH / 6;
int i;
for (i = 0; i < pset->nPolygons; i++, p++)
{
if (!p->effectParameters)
{
p->effectParameters = calloc (1, sizeof (AirplaneEffectParameters));
}
if (!p->effectParameters)
{
compLogMessage (w->screen->display, "animation",
CompLogLevelError, "Not enough memory");
return;
}
AirplaneEffectParameters *aep = p->effectParameters;
p->moveStartTime = 0.00;
p->moveDuration = 0.19;
aep->moveStartTime2 = 0.19;
aep->moveDuration2 = 0.19;
aep->moveStartTime3 = 0.38;
aep->moveDuration3 = 0.19;
aep->moveStartTime4 = 0.58;
aep->moveDuration4 = 0.09;
aep->moveDuration5 = 0.41;
aep->flyFinalRotation.x = 90;
aep->flyFinalRotation.y = 10;
aep->flyTheta = 0;
aep->centerPosFly.x = 0;
aep->centerPosFly.y = 0;
aep->centerPosFly.z = 0;
aep->flyScale = 0;
aep->flyFinalScale = 6 * (winLimitsW / (w->screen->width / 2));
switch (i)
{
case 0:
p->rotAxisOffset.x = -H4;
p->rotAxisOffset.y = H4;
p->rotAxis.x = 1.00;
p->rotAxis.y = 1.00;
p->rotAxis.z = 0.00;
p->finalRotAng = 179.5;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = 84;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = 0;
aep->rotAxisB.x = 0.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = 0;
break;
case 1:
p->rotAxisOffset.x = -H4;
p->rotAxisOffset.y = H4;
p->rotAxis.x = 1.00;
p->rotAxis.y = 1.00;
p->rotAxis.z = 0.00;
p->finalRotAng = 179.5;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = 84;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = H6;
aep->rotAxisB.x = 1.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = -84;
break;
case 2:
p->moveDuration = 0.00;
p->rotAxisOffset.x = 0;
p->rotAxisOffset.y = 0;
p->rotAxis.x = 0.00;
p->rotAxis.y = 0.00;
p->rotAxis.z = 0.00;
p->finalRotAng = 0;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = 84;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = H6;
aep->rotAxisB.x = 1.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = -84;
break;
case 3:
p->moveDuration = 0.00;
p->rotAxisOffset.x = 0;
p->rotAxisOffset.y = 0;
p->rotAxis.x = 0.00;
p->rotAxis.y = 0.00;
p->rotAxis.z = 0.00;
p->finalRotAng = 0;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = 84;
aep->moveDuration3 = 0.00;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = 0;
aep->rotAxisB.x = 0.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = 0;
break;
case 4:
p->moveDuration = 0.00;
p->rotAxisOffset.x = 0;
p->rotAxisOffset.y = 0;
p->rotAxis.x = 0.00;
p->rotAxis.y = 0.00;
p->rotAxis.z = 0.00;
p->finalRotAng = 0;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = -84;
aep->moveDuration3 = 0.00;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = 0;
aep->rotAxisB.x = 0.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = 0;
break;
case 5:
p->moveDuration = 0.00;
p->rotAxisOffset.x = 0;
p->rotAxisOffset.y = 0;
p->rotAxis.x = 0.00;
p->rotAxis.y = 0.00;
p->rotAxis.z = 0.00;
p->finalRotAng = 0;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = -84;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = -H6;
aep->rotAxisB.x = 1.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = 84;
break;
case 6:
p->rotAxisOffset.x = -H4;
p->rotAxisOffset.y = -H4;
p->rotAxis.x = 1.00;
p->rotAxis.y = -1.00;
p->rotAxis.z = 0.00;
p->finalRotAng = -179.5;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = -84;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = -H6;
aep->rotAxisB.x = 1.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = 84;
break;
case 7:
p->rotAxisOffset.x = -H4;
p->rotAxisOffset.y = -H4;
p->rotAxis.x = 1.00;
p->rotAxis.y = -1.00;
p->rotAxis.z = 0.00;
p->finalRotAng = -179.5;
aep->rotAxisOffsetA.x = 0;
aep->rotAxisOffsetA.y = 0;
aep->rotAxisA.x = 1.00;
aep->rotAxisA.y = 0.00;
aep->rotAxisA.z = 0.00;
aep->finalRotAngA = -84;
aep->rotAxisOffsetB.x = 0;
aep->rotAxisOffsetB.y = 0;
aep->rotAxisB.x = 0.00;
aep->rotAxisB.y = 0.00;
aep->rotAxisB.z = 0.00;
aep->finalRotAngB = 0;
break;
}
}
if (airplanePathLength >= 1)
pset->allFadeDuration = 0.30f / airplanePathLength;
else
pset->allFadeDuration = 0.30f;
pset->doDepthTest = TRUE;
pset->doLighting = TRUE;
pset->correctPerspective = CorrectPerspectivePolygon;
pset->extraPolygonTransformFunc =
&AirplaneExtraPolygonTransformFunc;
// Duration extension
aw->animTotalTime *= 2 + airplanePathLength;
aw->animRemainingTime = aw->animTotalTime;
}
void
fxAirplane3DLinearAnimStepPolygon (CompWindow * w,
PolygonObject * p,
float forwardProgress)
{
ANIM_SCREEN (w->screen);
ANIM_WINDOW (w);
float airplanePathLength =
animGetF (as, aw, ANIM_SCREEN_OPTION_AIRPLANE_PATHLENGTH);
Bool airplaneFly2TaskBar =
animGetB (as, aw, ANIM_SCREEN_OPTION_AIRPLANE_FLY2TOM);
AirplaneEffectParameters *aep = p->effectParameters;
/* Phase1: folding: flaps, folding center, folding wings.
* Phase2: rotate and fly.
*/
if (forwardProgress > p->moveStartTime &&
forwardProgress < aep->moveStartTime4)
// Phase1: folding: flaps, center, wings.
{
float moveProgress1 = forwardProgress - p->moveStartTime;
if (p->moveDuration > 0)
moveProgress1 /= p->moveDuration;
else
moveProgress1 = 0;
if (moveProgress1 < 0)
moveProgress1 = 0;
else if (moveProgress1 > 1)
moveProgress1 = 1;
float moveProgress2 = forwardProgress - aep->moveStartTime2;
if (aep->moveDuration2 > 0)
moveProgress2 /= aep->moveDuration2;
else
moveProgress2 = 0;
if (moveProgress2 < 0)
moveProgress2 = 0;
else if (moveProgress2 > 1)
moveProgress2 = 1;
float moveProgress3 = forwardProgress - aep->moveStartTime3;
if (aep->moveDuration3 > 0)
moveProgress3 /= aep->moveDuration3;
else
moveProgress3 = 0;
if (moveProgress3 < 0)
moveProgress3 = 0;
else if (moveProgress3 > 1)
moveProgress3 = 1;
p->centerPos.x = p->centerPosStart.x;
p->centerPos.y = p->centerPosStart.y;
p->centerPos.z = p->centerPosStart.z;
p->rotAngle = moveProgress1 * p->finalRotAng;
aep->rotAngleA = moveProgress2 * aep->finalRotAngA;
aep->rotAngleB = moveProgress3 * aep->finalRotAngB;
aep->flyRotation.x = 0;
aep->flyRotation.y = 0;
aep->flyRotation.z = 0;
aep->flyScale = 0;
}
else if (forwardProgress >= aep->moveStartTime4)
// Phase2: rotate and fly
{
float moveProgress4 = forwardProgress - aep->moveStartTime4;
if (aep->moveDuration4 > 0)
moveProgress4 /= aep->moveDuration4;
if (moveProgress4 < 0)
moveProgress4 = 0;
else if (moveProgress4 > 1)
moveProgress4 = 1;
float moveProgress5 = forwardProgress - (aep->moveStartTime4 + .01);
if (aep->moveDuration5 > 0)
moveProgress5 /= aep->moveDuration5;
if (moveProgress5 < 0)
moveProgress5 = 0;
else if (moveProgress5 > 1)
moveProgress5 = 1;
p->rotAngle = p->finalRotAng;
aep->rotAngleA = aep->finalRotAngA;
aep->rotAngleB = aep->finalRotAngB;
aep->flyRotation.x = moveProgress4 * aep->flyFinalRotation.x;
aep->flyRotation.y = moveProgress4 * aep->flyFinalRotation.y;
// flying path
float icondiffx = 0;
aep->flyTheta = moveProgress5 * -M_PI_2 * airplanePathLength;
aep->centerPosFly.x = w->screen->width * .4 * sin (2 * aep->flyTheta);
if (((aw->curWindowEvent == WindowEventMinimize ||
aw->curWindowEvent == WindowEventUnminimize) &&
airplaneFly2TaskBar) ||
aw->curWindowEvent == WindowEventOpen ||
aw->curWindowEvent == WindowEventClose)
{
// flying path ends at icon/pointer
int sign = 1;
if (aw->curWindowEvent == WindowEventUnminimize ||
aw->curWindowEvent == WindowEventOpen)
sign = -1;
icondiffx =
(((aw->icon.x + aw->icon.width / 2)
- (p->centerPosStart.x +
sign * w->screen->width * .4 *
sin (2 * -M_PI_2 * airplanePathLength))) *
moveProgress5);
aep->centerPosFly.y =
((aw->icon.y + aw->icon.height / 2) -
p->centerPosStart.y) *
-sin (aep->flyTheta / airplanePathLength);
}
else
{
if (p->centerPosStart.y < w->screen->height * .33 ||
p->centerPosStart.y > w->screen->height * .66)
aep->centerPosFly.y =
w->screen->height * .6 * sin (aep->flyTheta / 3.4);
else
aep->centerPosFly.y =
w->screen->height * .4 * sin (aep->flyTheta / 3.4);
if (p->centerPosStart.y < w->screen->height * .33)
aep->centerPosFly.y *= -1;
}
aep->flyFinalRotation.z =
((atan (2.0) + M_PI_2) * sin (aep->flyTheta) - M_PI_2) * 180 / M_PI;
aep->flyFinalRotation.z += 90;
if (aw->curWindowEvent == WindowEventMinimize ||
aw->curWindowEvent == WindowEventClose)
{
aep->flyFinalRotation.z *= -1;
}
else if (aw->curWindowEvent == WindowEventUnminimize ||
aw->curWindowEvent == WindowEventOpen)
{
aep->centerPosFly.x *= -1;
}
aep->flyRotation.z = aep->flyFinalRotation.z;
p->centerPos.x = p->centerPosStart.x + aep->centerPosFly.x + icondiffx;
p->centerPos.y = p->centerPosStart.y + aep->centerPosFly.y;
p->centerPos.z = p->centerPosStart.z + aep->centerPosFly.z;
aep->flyScale = moveProgress5 * aep->flyFinalScale;
}
}
void
AirplaneExtraPolygonTransformFunc (PolygonObject * p)
{
AirplaneEffectParameters *aep = p->effectParameters;
glRotatef (aep->flyRotation.x, 1, 0, 0); //rotate on axis X
glRotatef (-aep->flyRotation.y, 0, 1, 0); // rotate on axis Y
glRotatef (aep->flyRotation.z, 0, 0, 1); // rotate on axis Z
glScalef (1.0 / (1.0 + aep->flyScale),
1.0 / (1.0 + aep->flyScale), 1.0 / (1.0 + aep->flyScale));
// Move by "rotation axis offset A"
glTranslatef (aep->rotAxisOffsetA.x, aep->rotAxisOffsetA.y,
aep->rotAxisOffsetA.z);
// Rotate by desired angle A
glRotatef (aep->rotAngleA, aep->rotAxisA.x, aep->rotAxisA.y,
aep->rotAxisA.z);
// Move back to center from A
glTranslatef (-aep->rotAxisOffsetA.x, -aep->rotAxisOffsetA.y,
-aep->rotAxisOffsetA.z);
// Move by "rotation axis offset B"
glTranslatef (aep->rotAxisOffsetB.x, aep->rotAxisOffsetB.y,
aep->rotAxisOffsetB.z);
// Rotate by desired angle B
glRotatef (aep->rotAngleB, aep->rotAxisB.x, aep->rotAxisB.y,
aep->rotAxisB.z);
// Move back to center from B
glTranslatef (-aep->rotAxisOffsetB.x, -aep->rotAxisOffsetB.y,
-aep->rotAxisOffsetB.z);
}
Bool
fxAirplane3DAnimStep (CompScreen * s,
CompWindow * w,
float time)
{
ANIM_WINDOW (w);
if (!polygonsAnimStep (s, w, time))
return FALSE;
// Make sure the airplane always flies towards mouse pointer
if (aw->curWindowEvent == WindowEventClose)
getMousePointerXY(s, &aw->icon.x, &aw->icon.y);
return TRUE;
}
syntax highlighted by Code2HTML, v. 0.9.1