From a476ea182f32888577bae2f56c1693abd524dfb3 Mon Sep 17 00:00:00 2001 From: Timo Lotterbach Date: Thu, 22 Nov 2012 13:17:40 +0100 Subject: [PATCH] LayerManagerControl: added feature "demo" "demo" is used to run a number of effects on the rendered scene. Currently demo modes 0 to 4 are available. Signed-off-by: Timo Lotterbach --- .../LayerManagerControl/CMakeLists.txt | 1 + .../LayerManagerControl/include/LMControl.h | 11 + .../LayerManagerControl/src/commands.cpp | 7 + .../LayerManagerControl/src/demo.cpp | 741 +++++++++++++++++++++ 4 files changed, 760 insertions(+) create mode 100644 LayerManagerExamples/LayerManagerControl/src/demo.cpp diff --git a/LayerManagerExamples/LayerManagerControl/CMakeLists.txt b/LayerManagerExamples/LayerManagerControl/CMakeLists.txt index df083c2..c865758 100644 --- a/LayerManagerExamples/LayerManagerControl/CMakeLists.txt +++ b/LayerManagerExamples/LayerManagerControl/CMakeLists.txt @@ -35,6 +35,7 @@ add_executable(${PROJECT_NAME} src/analyze.cpp src/common.cpp src/control.cpp + src/demo.cpp src/Expression.cpp src/ExpressionInterpreter.cpp src/print.cpp diff --git a/LayerManagerExamples/LayerManagerControl/include/LMControl.h b/LayerManagerExamples/LayerManagerControl/include/LMControl.h index 028978c..0a78642 100644 --- a/LayerManagerExamples/LayerManagerControl/include/LMControl.h +++ b/LayerManagerExamples/LayerManagerControl/include/LMControl.h @@ -301,4 +301,15 @@ void scatterAll(); t_scene_data getScatteredScene(t_scene_data* pInitialScene); +//============================================================================= +//demo.cpp +//============================================================================= + +/* + * Run a set of effects on the rendered scene depending on the parameter. + * The function accepts values in range 0-4 + */ +void demo(int mode); + + #endif diff --git a/LayerManagerExamples/LayerManagerControl/src/commands.cpp b/LayerManagerExamples/LayerManagerControl/src/commands.cpp index 7bcfb0b..eaa81df 100644 --- a/LayerManagerExamples/LayerManagerControl/src/commands.cpp +++ b/LayerManagerExamples/LayerManagerControl/src/commands.cpp @@ -557,3 +557,10 @@ COMMAND("scatter all") scatterAll(); } +//============================================================================= +COMMAND("demo ") +//============================================================================= +{ + int mode = (int) input->getInt("animation_mode"); + demo(mode); +} diff --git a/LayerManagerExamples/LayerManagerControl/src/demo.cpp b/LayerManagerExamples/LayerManagerControl/src/demo.cpp new file mode 100644 index 0000000..56d2a57 --- /dev/null +++ b/LayerManagerExamples/LayerManagerControl/src/demo.cpp @@ -0,0 +1,741 @@ +/*************************************************************************** + * + * Copyright 2012 BMW Car IT GmbH + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include "ilm_client.h" +#include "LMControl.h" + +#include +using std::min; +using std::max; + +#include + + +#include +using std::cout; +using std::cin; +using std::cerr; +using std::endl; + +#include +using std::dec; +using std::hex; + +#include + +#include +using std::vector; + + + +namespace +{ + +typedef void (*t_pDemoAnimatorFunc)(t_scene_data* pInitialScene, t_scene_data* pDemoScene, bool* pStopDemo); + +void demoAnimatorDownwards(t_scene_data* pInitialScene, t_scene_data* pDemoScene, bool* pStopDemo) +{ + //get rendered surfaces + vector renderedSurfaces = getSceneRenderOrder(pDemoScene); + + //make random scale factors to scale down surfaces + float maxScale = 0.7; + float minScale = 0.2; + float rangeScale = maxScale - minScale; + + srand((unsigned) time(0)); + map surfaceScale; + + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + surfaceScale[surface] = minScale + rangeScale * (1.0 * rand() / RAND_MAX); + } + + //make random speeds (in pixel) + t_ilm_int maxSpeed = 6; + t_ilm_int minSpeed = 2; + t_ilm_int rangeSpeed = maxSpeed - minSpeed; + + srand((unsigned) time(0)); + map surfaceSpeed; + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + surfaceSpeed[surface] = minSpeed + static_cast(rangeScale* (1.0 * rand() / RAND_MAX)); + surfaceSpeed[surface] = minSpeed + + (static_cast(surfaceSpeed[surface] * (pow(2 + surfaceScale[surface], 2) - 4))); + } + + //set random direction + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + //set 50% of surfaces to move in -ve y direction + surfaceSpeed[surface] *= rand() % 2 ? -1 : 1; + } + + + //get surface positions and set initial positions + map surfaceCoordinates; + + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + ilmSurfaceProperties& surfaceProperties = + pDemoScene->surfaceProperties[surface]; + + //get current destination region AND scale surface dimensions + tuple4 coordinates(surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destX + static_cast(surfaceScale[surface] * surfaceProperties.destWidth), + surfaceProperties.destY + static_cast(surfaceScale[surface] * surfaceProperties.destHeight)); + + //make random X position to make surfaces spread in the screen + int screenWidthMidpoint = pDemoScene->screenWidth / 2; + int surfaceWidth = coordinates.z - coordinates.x; + + //make a random X position so that the surface stays totally displayable inside the screen + int maxX = pDemoScene->screenWidth - surfaceWidth; + int xRandom = static_cast(maxX * 1.0 * rand() / RAND_MAX); + + coordinates.x = xRandom; + coordinates.z = xRandom + surfaceWidth; + + surfaceCoordinates[surface] = coordinates; + } + + //sleeping time + long sleepTimeMillis = 25; + + //start animation ! + while(! *pStopDemo) + { + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + ilmSurfaceProperties& properties = pDemoScene->surfaceProperties[surface]; + tuple4& coordinates = surfaceCoordinates[surface]; + int speed = surfaceSpeed[surface]; + + //if out: get back to screen + if (coordinates.y >= static_cast(pDemoScene->screenHeight)) + { + //reset to top + coordinates.y = coordinates.y - coordinates.w; + coordinates.w = 0; + } + + //move + coordinates.y += abs(surfaceSpeed[surface]); + coordinates.w += abs(surfaceSpeed[surface]); + + //if the upper part is not visible remove it from the source and destination regions + if (coordinates.y <= 0) + { + //set source region to only the visible part of the surface + int ySource = static_cast(-coordinates.y / surfaceScale[surface]); + ilm_surfaceSetSourceRectangle(surface, 0, ySource, properties.sourceWidth, properties.sourceHeight - ySource); + + //set the destination region AT THE TOP of the layer used for displaying the surface + ilm_surfaceSetDestinationRectangle(surface, + coordinates.x, + 0, + max(0, coordinates.z - coordinates.x), + max(0, coordinates.w)); + } + else + { + //set source region to whole surface + ilm_surfaceSetSourceRectangle(surface, 0, 0, properties.sourceWidth, properties.sourceHeight); + + //set destination region to the region on the layer used for displaying the surface + ilm_surfaceSetDestinationRectangle(surface, + coordinates.x, + coordinates.y, + max(0, coordinates.z - coordinates.x), + max(0, coordinates.w - coordinates.y)); + } + + surfaceCoordinates[surface] = coordinates; + } + + ilm_commitChanges(); + usleep(sleepTimeMillis * 1000); + } +} + +void demoAnimatorRandomDirections(t_scene_data* pInitialScene, t_scene_data* pDemoScene, bool* pStopDemo) +{ + //get rendered surfaces + vector renderedSurfaces = getSceneRenderOrder(pDemoScene); + + //make random scale factors to scale down surfaces + float maxScale = 0.7; + float minScale = 0.2; + float rangeScale = maxScale - minScale; + + srand((unsigned) time(0)); + map surfaceScale; + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + surfaceScale[surface] = minScale + rangeScale * (1.0 * rand() / RAND_MAX); + } + + //make random speeds (in pixel) + t_ilm_int maxSpeed = 12; + t_ilm_int minSpeed = 2; + t_ilm_int rangeSpeed = maxSpeed - minSpeed; + + srand((unsigned) time(0)); + map surfaceSpeed; + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + surfaceSpeed[surface] = minSpeed + static_cast(rangeScale * (1.0 * rand() / RAND_MAX)); + surfaceSpeed[surface] = minSpeed + + (static_cast(surfaceSpeed[surface] * (pow(2 + surfaceScale[surface], 2) - 4))); + } + + //set random direction + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + //set 50% of surfaces to move in -ve y direction + surfaceSpeed[surface] *= rand() % 2 ? -1 : 1; + } + + //get surface positions and set initial positions + map surfaceCoordinates; + + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + ilmSurfaceProperties& surfaceProperties = pDemoScene->surfaceProperties[surface]; + + //get current destination region AND scale surface dimensions + tuple4 coordinates(surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destX + static_cast(surfaceScale[surface] * surfaceProperties.destWidth), + surfaceProperties.destY + static_cast(surfaceScale[surface] * surfaceProperties.destHeight)); + + //make random X position to make surfaces spread in the screen + int screenWidthMidpoint = pDemoScene->screenWidth / 2; + int surfaceWidth = coordinates.z - coordinates.x; + + //make a random X position so that the surface stays totally displayable inside the screen + int maxX = pDemoScene->screenWidth - surfaceWidth; + int xRandom = static_cast(maxX * 1.0 * rand() / RAND_MAX); + + coordinates.x = xRandom; + coordinates.z = xRandom + surfaceWidth; + + surfaceCoordinates[surface] = coordinates; + } + + //sleeping time + long sleepTimeMillis = 25; + + //start animation ! + while(! *pStopDemo) + { + //set transparency to be inversly proportional to scale + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + + float opacity = min(1.0, 1.1 - surfaceScale[surface]); + ilm_surfaceSetOpacity(surface, opacity); + } + + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + ilmSurfaceProperties& properties = pDemoScene->surfaceProperties[surface]; + tuple4& coordinates = surfaceCoordinates[surface]; + int speed = surfaceSpeed[surface]; + + //if out: get back to screen + if (coordinates.y >= static_cast(pDemoScene->screenHeight) && speed > 0) + { + //reset to top + coordinates.y = coordinates.y - coordinates.w; + coordinates.w = 0; + } + else if (coordinates.w <= 0 && speed < 0) + { + coordinates.w = pDemoScene->screenHeight + coordinates.w - coordinates.y; + coordinates.y = pDemoScene->screenHeight; + } + + //move + coordinates.y += surfaceSpeed[surface]; + coordinates.w += surfaceSpeed[surface]; + + + //if the upper part is not visible remove it from the source and destination regions + if (coordinates.y <= 0) + { + //set source region to only the visible part of the surface + int ySource = static_cast(-coordinates.y / surfaceScale[surface]); + ilm_surfaceSetSourceRectangle(surface, 0, ySource, properties.sourceWidth, properties.sourceHeight - ySource); + + //set the destination region AT THE TOP of the layer used for displaying the surface + ilm_surfaceSetDestinationRectangle(surface, + coordinates.x, + 0, + max(0, coordinates.z - coordinates.x), + max(0, coordinates.w)); + } + else + { + //set source region to whole surface + ilm_surfaceSetSourceRectangle(surface, 0, 0, properties.sourceWidth, properties.sourceHeight); + + //set destination region to the region on the layer used for displaying the surface + ilm_surfaceSetDestinationRectangle(surface, + coordinates.x, + coordinates.y, + max(0, coordinates.z - coordinates.x), + max(0, coordinates.w - coordinates.y)); + } + + surfaceCoordinates[surface] = coordinates; + } + + ilm_commitChanges(); + usleep(sleepTimeMillis * 1000); + } +} + +void demoAnimatorWaterfall(t_scene_data* pInitialScene, t_scene_data* pDemoScene, bool* pStopDemo) +{ + //get rendered surfaces + vector renderedSurfaces = getSceneRenderOrder(pDemoScene); + + //make random scale factors to scale down surfaces + float maxScale = 0.7; + float minScale = 0.2; + float rangeScale = maxScale - minScale; + + srand((unsigned) time(0)); + map surfaceScale; + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + surfaceScale[surface] = minScale + rangeScale * (1.0 * rand() / RAND_MAX); + } + + //make random speeds (in pixel) + t_ilm_int maxSpeed = 12; + t_ilm_int minSpeed = 2; + t_ilm_int rangeSpeed = maxSpeed - minSpeed; + + srand((unsigned) time(0)); + map surfaceSpeed; + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + surfaceSpeed[surface] = minSpeed + static_cast(rangeScale * (1.0 * rand() / RAND_MAX)); + surfaceSpeed[surface] = minSpeed + + (static_cast(surfaceSpeed[surface] * (pow(2 + surfaceScale[surface], 2) - 4))); + } + + //set random direction + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + //set 50% of surfaces to move in -ve y direction + surfaceSpeed[surface] *= rand() % 2 ? -1 : 1; + } + + //get surface positions and set initial positions + map surfaceCoordinates; + + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + ilmSurfaceProperties& surfaceProperties = pDemoScene->surfaceProperties[surface]; + + //get current destination region AND scale surface dimensions + tuple4 coordinates(surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destX + static_cast(surfaceScale[surface] * surfaceProperties.destWidth), + surfaceProperties.destY + static_cast(surfaceScale[surface] * surfaceProperties.destHeight)); + + //make random X position to make surfaces spread in the screen + int screenWidthMidpoint = pDemoScene->screenWidth / 2; + int surfaceWidth = coordinates.z - coordinates.x; + + //make a random X position so that the surface stays totally displayable inside the screen + int maxX = pDemoScene->screenWidth - surfaceWidth; + int xRandom = static_cast(maxX * 1.0 * rand() / RAND_MAX); + + coordinates.x = xRandom; + coordinates.z = xRandom + surfaceWidth; + + surfaceCoordinates[surface] = coordinates; + } + + //sleeping time + long sleepTimeMillis = 25; + + //start animation ! + while(! *pStopDemo) + { + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + ilmSurfaceProperties& properties = pDemoScene->surfaceProperties[surface]; + tuple4& coordinates = surfaceCoordinates[surface]; + int speed = surfaceSpeed[surface]; + + //if out: get back to screen + if (coordinates.y >= static_cast(pDemoScene->screenHeight)) + { + //reset to top + coordinates.y = coordinates.y - coordinates.w; + coordinates.w = 0; + } + + t_ilm_float fraction = max(0.0, 1.0 * (coordinates.w) / (pDemoScene->screenHeight + coordinates.w - coordinates.y)); + t_ilm_float t = pow(3, 0.0251 + fraction); + int displacement = static_cast(t * abs(surfaceSpeed[surface])); + + t_ilm_float opacity = min(1.0, max(0.0, 1 - fraction)); //between 0 and 1 + ilm_surfaceSetOpacity(surface, opacity); + + //move + coordinates.y += displacement; + coordinates.w += displacement; + + //if the upper part is not visible remove it from the source and destination regions + if (coordinates.y <= 0) + { + //set source region to only the visible part of the surface + int ySource = static_cast(-coordinates.y / surfaceScale[surface]); + ilm_surfaceSetSourceRectangle(surface, + 0, + ySource, + properties.sourceWidth, + properties.sourceHeight - ySource); + + //set the destination region AT THE TOP of the layer used for displaying the surface + ilm_surfaceSetDestinationRectangle(surface, + coordinates.x, + 0, + max(0, coordinates.z - coordinates.x), + max(0, coordinates.w)); + } + else + { + //set source region to whole surface + ilm_surfaceSetSourceRectangle(surface, 0, 0, properties.sourceWidth, properties.sourceHeight); + + //set destination region to the region on the layer used for displaying the surface + ilm_surfaceSetDestinationRectangle(surface, + coordinates.x, + coordinates.y, + max(0, coordinates.z - coordinates.x), + max(0, coordinates.w - coordinates.y)); + } + + surfaceCoordinates[surface] = coordinates; + } + + ilm_commitChanges(); + usleep(sleepTimeMillis * 1000); + } +} + +void demoAnimatorZooming(t_scene_data* pInitialScene, t_scene_data* pDemoScene, bool* pStopDemo) +{ + //get rendered surfaces + vector renderedSurfaces = getSceneRenderOrder(pDemoScene); + + //set surface initial states + int screenHorizontalMidpoint = pDemoScene->screenWidth / 2; + int screenVerticalMidpoint = pDemoScene->screenHeight / 2; + + for (vector::iterator it = renderedSurfaces.begin(); + it != renderedSurfaces.end(); ++it) + { + t_ilm_surface surface = *it; + ilmSurfaceProperties& surfaceProperties = pDemoScene->surfaceProperties[surface]; + + surfaceProperties.destX = screenHorizontalMidpoint; + surfaceProperties.destY = screenVerticalMidpoint; + surfaceProperties.destHeight = 0; + surfaceProperties.destWidth = 0; + + ilm_surfaceSetDestinationRectangle(surface, + surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destWidth, + surfaceProperties.destHeight); + } + + //sleeping time + long sleepTimeMillis = 25; + + //start animation ! + + t_ilm_float t = 1; + + int currentSurfaceIndex = 0; + + while (!*pStopDemo) + { + t_ilm_surface surface = renderedSurfaces[currentSurfaceIndex]; + + ilmSurfaceProperties& surfaceProperties = pDemoScene->surfaceProperties[surface]; + //if currentsurface dimensions touch the screen: change surface and reset scale factor + if (surfaceProperties.destX == 0 || surfaceProperties.destY == 0) + { + t = 1; + surfaceProperties.destX = screenHorizontalMidpoint; + surfaceProperties.destY = screenVerticalMidpoint; + surfaceProperties.destHeight = 0; + surfaceProperties.destWidth = 0; + + currentSurfaceIndex = (currentSurfaceIndex + 1) % renderedSurfaces.size(); + t_ilm_layer layer = pDemoScene->screenLayers.begin()->second[0]; + + ilm_surfaceSetDestinationRectangle(surface, + surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destWidth, + surfaceProperties.destHeight); + + ilm_layerSetRenderOrder(layer, renderedSurfaces.data() + currentSurfaceIndex, 1); + } + else + { + t += t * 0.1; + int change = (int) t; + surfaceProperties.destX = max(0, (int) surfaceProperties.destX - change); + surfaceProperties.destY = max(0, (int) surfaceProperties.destY - change); + surfaceProperties.destWidth += 2 * change; + surfaceProperties.destHeight += 2 * change; + + ilm_surfaceSetDestinationRectangle(surface, + surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destWidth, + surfaceProperties.destHeight); + + float opacity = 1 / pow(t, 0.4); + ilm_surfaceSetOpacity(surface, opacity); + } + + ilm_commitChanges(); + usleep(sleepTimeMillis * 1000); + } +} + +void demoAnimatorCascadedZooming(t_scene_data* pInitialScene, t_scene_data* pDemoScene, bool* pStopDemo) +{ + //get rendered surfaces + vector renderedSurfaces = getSceneRenderOrder(pDemoScene); + + map scaleFactors; + //set surface initial states + int screenHorizontalMidpoint = pDemoScene->screenWidth / 2; + int screenVerticalMidpoint = pDemoScene->screenHeight / 2; + + for (int i = 0; i < renderedSurfaces.size(); ++i) + { + t_ilm_surface surface = renderedSurfaces[i]; + ilmSurfaceProperties& surfaceProperties = pDemoScene->surfaceProperties[surface]; + + surfaceProperties.destX = screenHorizontalMidpoint; + surfaceProperties.destY = screenVerticalMidpoint; + surfaceProperties.destHeight = 0; + surfaceProperties.destWidth = 0; + + ilm_surfaceSetDestinationRectangle(surface, + surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destWidth, + surfaceProperties.destHeight); + + scaleFactors[surface] = 1; + } + + //sleeping time + long sleepTimeMillis = 25; + + //start animation ! + + while (!*pStopDemo) + { + for (int i = 0; i < renderedSurfaces.size(); ++i) + { + t_ilm_surface surface = renderedSurfaces[i]; + ilmSurfaceProperties& surfaceProperties = pDemoScene->surfaceProperties[surface]; + //if currentsurface dimensions touch the screen: change surface and reset scale factor + if (surfaceProperties.destX == 0 || surfaceProperties.destY == 0) + { + scaleFactors[surface] = 1; + + surfaceProperties.destX = screenHorizontalMidpoint; + surfaceProperties.destY = screenVerticalMidpoint; + surfaceProperties.destHeight = 0; + surfaceProperties.destWidth = 0; + + t_ilm_layer layer = pDemoScene->screenLayers.begin()->second[0]; + + ilm_surfaceSetDestinationRectangle(surface, + surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destWidth, + surfaceProperties.destHeight); + + ilm_commitChanges(); + //update render order + t_ilm_surface firstSurface = renderedSurfaces[0]; + for (int j = 1; j < renderedSurfaces.size(); ++j) + { + renderedSurfaces[j - 1] = renderedSurfaces[j]; + } + + renderedSurfaces[renderedSurfaces.size() - 1] = firstSurface; + + ilm_layerSetRenderOrder(layer, renderedSurfaces.data(), renderedSurfaces.size()); + ilm_commitChanges(); + } + else + { + //just some fancy function math that gives a special effect + scaleFactors[surface] = (1.0125, i + scaleFactors[surface] * 0.5); + + int change = (int) scaleFactors[surface]; + surfaceProperties.destX = max(0, (int) surfaceProperties.destX - change); + surfaceProperties.destY = max(0, (int) surfaceProperties.destY - change); + surfaceProperties.destWidth += 2 * change; + surfaceProperties.destHeight += 2 * change; + + ilm_surfaceSetDestinationRectangle(surface, + surfaceProperties.destX, + surfaceProperties.destY, + surfaceProperties.destWidth, + surfaceProperties.destHeight); + + float opacity = 1 / pow(scaleFactors[surface], 0.4f); + ilm_surfaceSetOpacity(surface, opacity); + } + } + + ilm_commitChanges(); + usleep(sleepTimeMillis * 1000); + } +} + +void* demoThreadCallback(void* param) +{ + //call function on parameters + map* paramMap = (map*) param; + + t_pDemoAnimatorFunc animator = (t_pDemoAnimatorFunc) paramMap->at("pAnimator"); + t_scene_data* pInitialScene = (t_scene_data*) paramMap->at("pInitialScene"); + t_scene_data* pDemoScene = (t_scene_data*) paramMap->at("pDemoScene"); + bool* pStopDemo= (bool*) paramMap->at("pStopDemo"); + + //call demo animator function ! + (*animator)(pInitialScene, pDemoScene, pStopDemo); + + return NULL; +} + +} //end of anonymous namespace + +void demo(int mode) +{ + vector animators; + animators.push_back(&demoAnimatorZooming); + animators.push_back(&demoAnimatorCascadedZooming); + animators.push_back(&demoAnimatorDownwards); + animators.push_back(&demoAnimatorRandomDirections); + animators.push_back(&demoAnimatorWaterfall); + + //if valid mode entered + if (mode >= 0 && mode < animators.size()) + { + //capture initial scene + t_scene_data initialScene; + captureSceneData(&initialScene); + + setSceneToRestore(&initialScene); + + //set dummy scene + t_scene_data demoScene = cloneToUniLayerScene(&initialScene); + setScene(&demoScene); + + //start animation + volatile bool stopDemo = false; + + map paramMap; + paramMap["pAnimator"] = (void*) animators[mode]; + paramMap["pInitialScene"] = (void*) &initialScene; + paramMap["pDemoScene"] = (void*) &demoScene; + paramMap["pStopDemo"] = (void*) &stopDemo; + + pthread_t demoThread; + pthread_create(&demoThread, NULL, demoThreadCallback, (void*) ¶mMap); + + //set initial scene (reset) + cout<<"Press ENTER to stop demo..."; + cin.get(); + + cout<<"Resetting scene..."; + cout.flush(); + + stopDemo = true; //this variable has to be checked in the animator function !! + pthread_join(demoThread, NULL); + + t_scene_data finalScene; + captureSceneData(&finalScene); + transformScene(&finalScene, &initialScene, 1000, 50); + setScene(&initialScene, true); + cout<<"done"<