<commit_before>#include <cinttypes>
#include <iostream>
#include <chrono>
#include <thread>
#include <cstdlib>

#include "ZBE/core/daemons/DaemonMaster.h"
#include "ZBE/core/entities/avatars/implementations/SimpleCollisioner.h"
#include "ZBE/core/events/Event.h"
#include "ZBE/core/events/EventStore.h"
#include "ZBE/core/events/TimeEvent.h"
#include "ZBE/core/events/InputEvent.h"
#include "ZBE/core/events/CollisionEvent2D.h"
#include "ZBE/core/events/generators/InputEventGenerator.h"
#include "ZBE/core/events/generators/CollisionEventGenerator.h"
#include "ZBE/core/events/generators/TimeEventGenerator.h"
#include "ZBE/core/events/handlers/Actuator.h"
#include "ZBE/core/system/SysTime.h"
#include "ZBE/core/tools/Timer.h"
#include "ZBE/core/system/SysError.h"
#include "ZBE/core/daemons/Punishers.h"
#include "ZBE/SDL/tools/SDLTimer.h"
#include "ZBE/SDL/system/SDLEventDispatcher.h"
#include "ZBE/SDL/system/Window.h"
#include "ZBE/SDL/drawers/SimpleSpriteSDLDrawer.h"
#include "ZBE/entities/adaptors/implementations/SimpleDrawableSimpleSpriteAdaptor.h"
#include "ZBE/entities/adaptors/implementations/BaseSphereMCMAPOAdaptor.h"
#include "ZBE/behaviors/UniformLinearMotion.h"
#include "ZBE/archetypes/Mobile.h"
#include "ZBE/archetypes/MobileAPO.h"
#include "ZBE/actuators/MovableBouncer.h"

#include "gamemain.h"
#include "game/GameReactor.h"
#include "game/entities/GameBall.h"
#include "game/entities/GameBoard.h"
#include "game/entities/GameBlock.h"
#include "game/events/handlers/StepInputHandler.h"
#include "game/events/handlers/ExitInputHandler.h"
#include "game/events/handlers/GameBallBouncer.h"

int gamemain(int, char** ) {

  printf("--- GAME main ---\n\n");

  enum {
    INPUTEVENT = 0,
    COLLISIONEVENT = 1,
    TIMEEVENT = 2,

    COLLISIONATORLIST = 1,
    MOBILELIST = 1,
    BALLACTUATORLIST = 1,
    COLLISIONABLELIST = 1,
    BOARDACTUATORLIST = 1,
    BRICKACTUATORLIST = 2,

    WIDTH = 1024,
    HEIGHT = 768
  };

  const char ballfilename[] = "data/images/zombieball/zomball_st_32.png";
  const char brickfilename[] = "data/images/zombieball/braikn_32.png";
  uint64_t ballgraphics;
  uint64_t brickgraphics;

  printf("3 / 5 %d\n", 3/5);fflush(stdout);
  printf("2 / 5 %d\n", 2/5);fflush(stdout);

  printf("|=================== Building up system ===================|\n");fflush(stdout);
  printf("Event store\n");fflush(stdout);
  printf("Will store all event independently of its type\n");fflush(stdout);
  zbe::EventStore& store = zbe::EventStore::getInstance();
  printf("|------------------------ Input Event Generator-------------|\n");fflush(stdout);
  printf("Building SDLEventDispatcher\n");fflush(stdout);
  printf("Will extract data from SDL and get it usable for the engine\n");fflush(stdout);
  zbe::SDLEventDispatcher & sdlEventDist = zbe::SDLEventDispatcher::getInstance();
  printf("Acquiring InputBuffer\n");fflush(stdout);
  printf("SDLEventDispatcher Will store input changes for a frame into it\n");fflush(stdout);
  zbe::InputBuffer * inputBuffer = sdlEventDist.getInputBuffer();
  printf("Acquiring and configuring InputEventGenerator with that InputReader\n");fflush(stdout);
  printf("Will read events from the InputReader and send them to the store\n");fflush(stdout);
  printf("Input events will use id 0\n");fflush(stdout);
  zbe::InputEventGenerator ieg(inputBuffer,INPUTEVENT);
  printf("|------------------- Collision Event Generator-------------|\n");fflush(stdout);
  //zbe::TicketedForwardList<zbe::CollisionerEntity<GameReactor>*> cnl;
  printf("Building list for collisionator entinties. Currently empty.\n");fflush(stdout);
  printf("It will store entities that will search for a collision.\n");fflush(stdout);
  zbe::TicketedForwardList<zbe::CollisionatorEntity<game::GameReactor>*> ctl;
  printf("Acquiring singleton list-manager for this list (ctl).\n");fflush(stdout);
  zbe::ListManager< zbe::TicketedForwardList<zbe::CollisionatorEntity<game::GameReactor>*> >& lmct = zbe::ListManager< zbe::TicketedForwardList<zbe::CollisionatorEntity<game::GameReactor>*> >::getInstance();
  printf("Storing ctl in that list-manager.\n");fflush(stdout);
  lmct.insert(COLLISIONATORLIST, &ctl);
  printf("Building collision event generator with list id and the event id to use (1).\n");fflush(stdout);
  zbe::CollisionEventGenerator<game::GameReactor> ceg(COLLISIONATORLIST, COLLISIONEVENT);
  printf("|------------------- Time Event Generator -----------------|\n");fflush(stdout);
  printf("Building time event generator with the event id to use (2)\n");fflush(stdout);
  zbe::TimeEventGenerator teg(TIMEEVENT);
  printf("|------------------------- Time ---------------------------|\n");fflush(stdout);
  printf("Building a SDL implementation of Timer\n");fflush(stdout);
  zbe::Timer *sysTimer = new zbe::SDLTimer(true);
  printf("Acquiring and configuring SysTime with that Timer\n");fflush(stdout);
  printf("It will be the time reference for all the game context\n");fflush(stdout);
  zbe::SysTime &sysTime = zbe::SysTime::getInstance();
  sysTime.setSystemTimer(sysTimer);
  printf("|-------------------- Drawing system ----------------------|\n");fflush(stdout);
  printf("Building the window to draw on\n");fflush(stdout);
  zbe::Window window(WIDTH,HEIGHT);
  ballgraphics = window.loadImg(ballfilename);
  brickgraphics = window.loadImg(brickfilename);
  printf("Building the drawer to paint SimpleSprite's \n");fflush(stdout);
  zbe::SimpleSpriteSDLDrawer drawer(&window);
  printf("|-------------------- Daemons ----------------------|\n");fflush(stdout);
  zbe::DaemonMaster dMaster;
  std::vector<zbe::Mobile<2>*> vmobile;
  zbe::ListManager< std::vector<zbe::Mobile<2>*> >& lmmobile = zbe::ListManager< std::vector<zbe::Mobile<2>*> >::getInstance();
  lmmobile.insert(MOBILELIST, &vmobile);
  std::shared_ptr<zbe::Daemon> bball(new  zbe::BehaviorDaemon< zbe::Mobile<2>, std::vector<zbe::Mobile<2>*> >(new zbe::UniformLinearMotion<2>(), MOBILELIST));
  dMaster.addDaemon(bball);
  printf("|------------------- Creating entities --------------------|\n");fflush(stdout);
  printf("Creating drawables list\n");fflush(stdout);
  std::forward_list<zbe::SimpleSpriteEntity*> sprites;

  printf("Creating a ball and giving it a position and size\n");fflush(stdout);

  //ball
  std::forward_list< zbe::Actuator< zbe::MovableCollisioner<game::GameReactor, 2>, game::GameReactor >*> ballActuatorsList;
  zbe::ListManager< std::forward_list< zbe::Actuator< zbe::MovableCollisioner<game::GameReactor, 2>, game::GameReactor >* > >& lmBallActuatorsList = zbe::ListManager< std::forward_list< zbe::Actuator< zbe::MovableCollisioner<game::GameReactor, 2>, game::GameReactor >* > >::getInstance();
  lmBallActuatorsList.insert(BALLACTUATORLIST, &ballActuatorsList);
  game::GameBallBouncer gbBouncer;
  ballActuatorsList.push_front(&gbBouncer);

  zbe::TicketedForwardList<zbe::CollisionerEntity<game::GameReactor>*> collisionablesList;
  zbe::ListManager<zbe::TicketedForwardList<zbe::CollisionerEntity<game::GameReactor>*> >& lmCollisionablesList = zbe::ListManager< zbe::TicketedForwardList<zbe::CollisionerEntity<game::GameReactor>*> >::getInstance();
  lmCollisionablesList.insert(COLLISIONABLELIST, &collisionablesList);

  printf("Building an sprite adaptor for the ball\n");fflush(stdout);
  zbe::SimpleSpriteAdaptor<zbe::Drawable>* spriteAdaptor = new zbe::SimpleDrawableSimpleSpriteAdaptor();
  zbe::BaseSphereMCMAPOAdaptor<game::GameReactor, 2> * movableCatorAdaptor = new zbe::BaseSphereMCMAPOAdaptor<game::GameReactor, 2>();
  game::ExitInputHandler terminator;
  ieg.addHandler(zbe::ZBEK_ESCAPE, &terminator);

  std::forward_list<game::GameBall*> balls;
  for(int i = 0; i<1 ; i++){
      game::GameBall* ball = new game::GameBall(WIDTH/2, HEIGHT/2, 16 , -162, -117, BALLACTUATORLIST, COLLISIONABLELIST, ballgraphics);
      //game::GameBall* ball = new game::GameBall(151, 132, 16 , -100, -100, BALLACTUATORLIST, COLLISIONABLELIST, ballgraphics);
      ctl.push_front(ball);
      ball->setSimpleSpriteAdaptor(spriteAdaptor);
      ball->setMovableCollisionatorAdaptor(movableCatorAdaptor);
      vmobile.push_back(ball);
      balls.push_front(ball);
    	sprites.push_front(ball);
  }

  printf("Creating the bricks\n");fflush(stdout);
  //bricks
  zbe::ListManager< std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> >& lmSimpleConerActuatorsList = zbe::ListManager< std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> >::getInstance();
  std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> brickActuatorsList;
  lmSimpleConerActuatorsList.insert(BRICKACTUATORLIST, &brickActuatorsList);
  //GameBlock(double x, double y, double width, double height, uint64_t graphics, uint64_t actuatorsList)
  game::GameBlock brick(50 ,50, 32, 32, brickgraphics, BRICKACTUATORLIST);
  brick.setSimpleSpriteAdaptor(spriteAdaptor);
  collisionablesList.push_front(&brick);
  sprites.push_front(&brick);

	printf("Creating the board and giving it a size\n");fflush(stdout);
  //board
  std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> boardActuatorsList;
  lmSimpleConerActuatorsList.insert(BOARDACTUATORLIST, &boardActuatorsList);
  game::GameBoard board(WIDTH, HEIGHT, BOARDACTUATORLIST);
  collisionablesList.push_front(&board);

  printf("|=================== Starting up system ===================|\n");fflush(stdout);
  printf("Starting SysTimer\n");fflush(stdout);
  sysTimer->start();
  printf("Acquiring sdl info for the first time\n");fflush(stdout);
  printf("Input data will be stored into the InputReader\n");fflush(stdout);
  sdlEventDist.run();
  printf("Updating system time.\n");fflush(stdout);
  sysTime.update();
  printf("Acquiring initial times.\n");fflush(stdout);
  int64_t endT = sysTime.getTotalTime();// instant at which the frame ends
  int64_t initT = 0;//Lets start
  printf("|==========================================================|\n");fflush(stdout);
  printf("initT = 0x%" PRIx64 " ", initT);fflush(stdout);
  printf("endT = 0x%" PRIx64 "\n", endT);fflush(stdout);

  bool keep = true;
  while(keep){

    /* Clear screen.
     */
    window.clear();

    /* Acquiring sdl info
     * Input data will be stored into the InputReader
     */
    sdlEventDist.run();

    /* Updating system time.
     */
    sysTime.update();

    /* Reading that updated time info
     */
    initT = endT;// init time
    endT = sysTime.getTotalTime(); //initT + (int64_t(1) << zbe::PRECISION_DIGITS); // instant at which the frame ends

    if((endT - 32768)>initT){
      initT = endT - 32768;
    }

    while (initT < endT) {
      /* Generating input events:
       * It will take the events that sdlEventDist has stored
       * into the InputReader and send it to the event store.
       */
      ieg.generate(initT,endT);
      teg.generate(initT,endT);
      ceg.generate(initT,endT);

      int64_t eventTime = store.getTime();
      if (eventTime <= endT) {
        dMaster.run(eventTime-initT);
        store.manageCurrent();
        initT = eventTime;
      } else {
        dMaster.run(endT-initT);
        store.clearStore();
        initT = endT;
      }
    }

    for(auto s : sprites){
        drawer.apply(s->getSimpleSprite().get());
    }

    /* If one or more error occurs, the ammount and the first one
     * wille be stored into SysError estructure, so it can be consulted.
     *
     * If there are errors, the first one will be prompted.
     */
    int errcount = zbe::SysError::getNErrors();
    if(errcount>0){
        printf("Error: %s",zbe::SysError::getFirstErrorString().c_str());fflush(stdout);
    }
    window.present();
  }

  return 0;
}
<commit_msg>Adding brick to gamemain. Multiple bricks. There is a problem with the collision/handler/behaviour system that make balls go through bricks. Dont worry, we have a solution.<commit_after>#include <cinttypes>
#include <iostream>
#include <chrono>
#include <thread>
#include <cstdlib>

#include "ZBE/core/daemons/DaemonMaster.h"
#include "ZBE/core/entities/avatars/implementations/SimpleCollisioner.h"
#include "ZBE/core/events/Event.h"
#include "ZBE/core/events/EventStore.h"
#include "ZBE/core/events/TimeEvent.h"
#include "ZBE/core/events/InputEvent.h"
#include "ZBE/core/events/CollisionEvent2D.h"
#include "ZBE/core/events/generators/InputEventGenerator.h"
#include "ZBE/core/events/generators/CollisionEventGenerator.h"
#include "ZBE/core/events/generators/TimeEventGenerator.h"
#include "ZBE/core/events/handlers/Actuator.h"
#include "ZBE/core/system/SysTime.h"
#include "ZBE/core/tools/Timer.h"
#include "ZBE/core/system/SysError.h"
#include "ZBE/core/daemons/Punishers.h"
#include "ZBE/SDL/tools/SDLTimer.h"
#include "ZBE/SDL/system/SDLEventDispatcher.h"
#include "ZBE/SDL/system/Window.h"
#include "ZBE/SDL/drawers/SimpleSpriteSDLDrawer.h"
#include "ZBE/entities/adaptors/implementations/SimpleDrawableSimpleSpriteAdaptor.h"
#include "ZBE/entities/adaptors/implementations/BaseSphereMCMAPOAdaptor.h"
#include "ZBE/behaviors/UniformLinearMotion.h"
#include "ZBE/archetypes/Mobile.h"
#include "ZBE/archetypes/MobileAPO.h"
#include "ZBE/actuators/MovableBouncer.h"

#include "gamemain.h"
#include "game/GameReactor.h"
#include "game/entities/GameBall.h"
#include "game/entities/GameBoard.h"
#include "game/entities/GameBlock.h"
#include "game/events/handlers/StepInputHandler.h"
#include "game/events/handlers/ExitInputHandler.h"
#include "game/events/handlers/GameBallBouncer.h"

int gamemain(int, char** ) {

  printf("--- GAME main ---\n\n");

  enum {
    INPUTEVENT = 0,
    COLLISIONEVENT = 1,
    TIMEEVENT = 2,

    COLLISIONATORLIST = 1,
    MOBILELIST = 1,
    BALLACTUATORLIST = 1,
    COLLISIONABLELIST = 1,
    BOARDACTUATORLIST = 1,
    BRICKACTUATORLIST = 2,

    WIDTH = 1024,
    HEIGHT = 768
  };

  const char ballfilename[] = "data/images/zombieball/zomball_st_32.png";
  const char brickfilename[] = "data/images/zombieball/braikn_32.png";
  uint64_t ballgraphics;
  uint64_t brickgraphics;

  printf("3 / 5 %d\n", 3/5);fflush(stdout);
  printf("2 / 5 %d\n", 2/5);fflush(stdout);

  printf("|=================== Building up system ===================|\n");fflush(stdout);
  printf("Event store\n");fflush(stdout);
  printf("Will store all event independently of its type\n");fflush(stdout);
  zbe::EventStore& store = zbe::EventStore::getInstance();
  printf("|------------------------ Input Event Generator-------------|\n");fflush(stdout);
  printf("Building SDLEventDispatcher\n");fflush(stdout);
  printf("Will extract data from SDL and get it usable for the engine\n");fflush(stdout);
  zbe::SDLEventDispatcher & sdlEventDist = zbe::SDLEventDispatcher::getInstance();
  printf("Acquiring InputBuffer\n");fflush(stdout);
  printf("SDLEventDispatcher Will store input changes for a frame into it\n");fflush(stdout);
  zbe::InputBuffer * inputBuffer = sdlEventDist.getInputBuffer();
  printf("Acquiring and configuring InputEventGenerator with that InputReader\n");fflush(stdout);
  printf("Will read events from the InputReader and send them to the store\n");fflush(stdout);
  printf("Input events will use id 0\n");fflush(stdout);
  zbe::InputEventGenerator ieg(inputBuffer,INPUTEVENT);
  printf("|------------------- Collision Event Generator-------------|\n");fflush(stdout);
  //zbe::TicketedForwardList<zbe::CollisionerEntity<GameReactor>*> cnl;
  printf("Building list for collisionator entinties. Currently empty.\n");fflush(stdout);
  printf("It will store entities that will search for a collision.\n");fflush(stdout);
  zbe::TicketedForwardList<zbe::CollisionatorEntity<game::GameReactor>*> ctl;
  printf("Acquiring singleton list-manager for this list (ctl).\n");fflush(stdout);
  zbe::ListManager< zbe::TicketedForwardList<zbe::CollisionatorEntity<game::GameReactor>*> >& lmct = zbe::ListManager< zbe::TicketedForwardList<zbe::CollisionatorEntity<game::GameReactor>*> >::getInstance();
  printf("Storing ctl in that list-manager.\n");fflush(stdout);
  lmct.insert(COLLISIONATORLIST, &ctl);
  printf("Building collision event generator with list id and the event id to use (1).\n");fflush(stdout);
  zbe::CollisionEventGenerator<game::GameReactor> ceg(COLLISIONATORLIST, COLLISIONEVENT);
  printf("|------------------- Time Event Generator -----------------|\n");fflush(stdout);
  printf("Building time event generator with the event id to use (2)\n");fflush(stdout);
  zbe::TimeEventGenerator teg(TIMEEVENT);
  printf("|------------------------- Time ---------------------------|\n");fflush(stdout);
  printf("Building a SDL implementation of Timer\n");fflush(stdout);
  zbe::Timer *sysTimer = new zbe::SDLTimer(true);
  printf("Acquiring and configuring SysTime with that Timer\n");fflush(stdout);
  printf("It will be the time reference for all the game context\n");fflush(stdout);
  zbe::SysTime &sysTime = zbe::SysTime::getInstance();
  sysTime.setSystemTimer(sysTimer);
  printf("|-------------------- Drawing system ----------------------|\n");fflush(stdout);
  printf("Building the window to draw on\n");fflush(stdout);
  zbe::Window window(WIDTH,HEIGHT);
  ballgraphics = window.loadImg(ballfilename);
  brickgraphics = window.loadImg(brickfilename);
  printf("Building the drawer to paint SimpleSprite's \n");fflush(stdout);
  zbe::SimpleSpriteSDLDrawer drawer(&window);
  printf("|-------------------- Daemons ----------------------|\n");fflush(stdout);
  zbe::DaemonMaster dMaster;
  std::vector<zbe::Mobile<2>*> vmobile;
  zbe::ListManager< std::vector<zbe::Mobile<2>*> >& lmmobile = zbe::ListManager< std::vector<zbe::Mobile<2>*> >::getInstance();
  lmmobile.insert(MOBILELIST, &vmobile);
  std::shared_ptr<zbe::Daemon> bball(new  zbe::BehaviorDaemon< zbe::Mobile<2>, std::vector<zbe::Mobile<2>*> >(new zbe::UniformLinearMotion<2>(), MOBILELIST));
  dMaster.addDaemon(bball);
  printf("|------------------- Creating entities --------------------|\n");fflush(stdout);
  printf("Creating drawables list\n");fflush(stdout);
  std::forward_list<zbe::SimpleSpriteEntity*> sprites;

  printf("Creating a ball and giving it a position and size\n");fflush(stdout);

  //ball
  std::forward_list< zbe::Actuator< zbe::MovableCollisioner<game::GameReactor, 2>, game::GameReactor >*> ballActuatorsList;
  zbe::ListManager< std::forward_list< zbe::Actuator< zbe::MovableCollisioner<game::GameReactor, 2>, game::GameReactor >* > >& lmBallActuatorsList = zbe::ListManager< std::forward_list< zbe::Actuator< zbe::MovableCollisioner<game::GameReactor, 2>, game::GameReactor >* > >::getInstance();
  lmBallActuatorsList.insert(BALLACTUATORLIST, &ballActuatorsList);
  game::GameBallBouncer gbBouncer;
  ballActuatorsList.push_front(&gbBouncer);

  zbe::TicketedForwardList<zbe::CollisionerEntity<game::GameReactor>*> collisionablesList;
  zbe::ListManager<zbe::TicketedForwardList<zbe::CollisionerEntity<game::GameReactor>*> >& lmCollisionablesList = zbe::ListManager< zbe::TicketedForwardList<zbe::CollisionerEntity<game::GameReactor>*> >::getInstance();
  lmCollisionablesList.insert(COLLISIONABLELIST, &collisionablesList);

  printf("Building an sprite adaptor for the ball\n");fflush(stdout);
  zbe::SimpleSpriteAdaptor<zbe::Drawable>* spriteAdaptor = new zbe::SimpleDrawableSimpleSpriteAdaptor();
  zbe::BaseSphereMCMAPOAdaptor<game::GameReactor, 2> * movableCatorAdaptor = new zbe::BaseSphereMCMAPOAdaptor<game::GameReactor, 2>();
  game::ExitInputHandler terminator;
  ieg.addHandler(zbe::ZBEK_ESCAPE, &terminator);

  std::forward_list<game::GameBall*> balls;
  for(int i = 0; i<1000 ; i++){//98.623993, 85.728439
      //game::GameBall* ball = new game::GameBall(98.623993, 85.728439, 16 , -100, -100, BALLACTUATORLIST, COLLISIONABLELIST, ballgraphics);
      game::GameBall* ball = new game::GameBall((rand()%200 + 400), (rand()%200 + 400), 16 , (rand()%200 - 100), (rand()%200 - 100), BALLACTUATORLIST, COLLISIONABLELIST, ballgraphics);
      ctl.push_front(ball);
      ball->setSimpleSpriteAdaptor(spriteAdaptor);
      ball->setMovableCollisionatorAdaptor(movableCatorAdaptor);
      vmobile.push_back(ball);
      balls.push_front(ball);
      sprites.push_front(ball);
  }

  printf("Creating the bricks\n");fflush(stdout);
  //bricks
  zbe::ListManager< std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> >& lmSimpleConerActuatorsList = zbe::ListManager< std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> >::getInstance();
  std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> brickActuatorsList;
  lmSimpleConerActuatorsList.insert(BRICKACTUATORLIST, &brickActuatorsList);
  for(int i = 0; i<8 ; i++){
      for(int j = 0; j<8 ; j++){
          game::GameBlock *brick = new game::GameBlock(i*51+ 100, j*32 + 100, 51, 32, brickgraphics, BRICKACTUATORLIST);
          brick->setSimpleSpriteAdaptor(spriteAdaptor);
          collisionablesList.push_front(brick);
          sprites.push_front(brick);
      }
  }

  printf("Creating the board and giving it a size\n");fflush(stdout);
  //board
  std::forward_list< zbe::Actuator<zbe::SimpleCollisioner<game::GameReactor>, game::GameReactor>*> boardActuatorsList;
  lmSimpleConerActuatorsList.insert(BOARDACTUATORLIST, &boardActuatorsList);
  game::GameBoard board(WIDTH, HEIGHT, BOARDACTUATORLIST);
  collisionablesList.push_front(&board);

  printf("|=================== Starting up system ===================|\n");fflush(stdout);
  printf("Starting SysTimer\n");fflush(stdout);
  sysTimer->start();
  printf("Acquiring sdl info for the first time\n");fflush(stdout);
  printf("Input data will be stored into the InputReader\n");fflush(stdout);
  sdlEventDist.run();
  printf("Updating system time.\n");fflush(stdout);
  sysTime.update();
  printf("Acquiring initial times.\n");fflush(stdout);
  int64_t endT = sysTime.getTotalTime();// instant at which the frame ends
  int64_t initT = 0;//Lets start
  printf("|==========================================================|\n");fflush(stdout);
  printf("initT = 0x%" PRIx64 " ", initT);fflush(stdout);
  printf("endT = 0x%" PRIx64 "\n", endT);fflush(stdout);

  int64_t maxFrameTime = zbe::SECOND / 64;

  bool keep = true;
  while(keep){

    /* Clear screen.
     */
    window.clear();

    /* Acquiring sdl info
     * Input data will be stored into the InputReader
     */
    sdlEventDist.run();

    /* Updating system time.
     */
    sysTime.update();

    /* Reading that updated time info
     */
    initT = endT;// init time
    endT = sysTime.getTotalTime(); //initT + (int64_t(1) << zbe::PRECISION_DIGITS); // instant at which the frame ends

    if((endT - maxFrameTime)>initT){
      initT = endT - maxFrameTime;
    }

    while (initT < endT) {
      /* Generating input events:
       * It will take the events that sdlEventDist has stored
       * into the InputReader and send it to the event store.
       */
      ieg.generate(initT,endT);
      teg.generate(initT,endT);
      ceg.generate(initT,endT);

      int64_t eventTime = store.getTime();
      if (eventTime <= endT) {
        dMaster.run(eventTime-initT);
        store.manageCurrent();
        initT = eventTime;
      } else {
        dMaster.run(endT-initT);
        store.clearStore();
        initT = endT;
      }
    }

    for(auto s : sprites){
        drawer.apply(s->getSimpleSprite().get());
    }

    /* If one or more error occurs, the ammount and the first one
     * wille be stored into SysError estructure, so it can be consulted.
     *
     * If there are errors, the first one will be prompted.
     */
    int errcount = zbe::SysError::getNErrors();
    if(errcount>0){
        printf("Error: %s",zbe::SysError::getFirstErrorString().c_str());fflush(stdout);
    }
    window.present();
  }

  return 0;
}
<|endoftext|>


<commit_before>/*
 * TTBlue Limiter Object
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTLimiter.h"

#define thisTTClass			TTLimiter
#define thisTTClassName		"limiter"
#define thisTTClassTags		"audio, processor, dynamics, limiter"

TT_AUDIO_CONSTRUCTOR,
	recover(0.0),
	lookaheadBufferIndex(0),
	lookaheadBuffer(NULL),
	gain(NULL),
	last(0.0),
	dcBlocker(kTTSym_dcblock),
	preamp(kTTSym_gain),
	maxBufferSize(512),
	attrMode(TT("exponential"))
{
	TTUInt16	initialMaxNumChannels = arguments;

	// register our attributes
	registerAttribute(TT("preamp"),		kTypeFloat64,	NULL,			(TTGetterMethod)&TTLimiter::getPreamp,		(TTSetterMethod)&TTLimiter::setPreamp);
	registerAttribute(TT("postamp"),	kTypeFloat64,	&attrPostamp,	(TTGetterMethod)&TTLimiter::getPostamp,		(TTSetterMethod)&TTLimiter::setPostamp);
	registerAttribute(TT("threshold"),	kTypeFloat64,	&attrThreshold,	(TTGetterMethod)&TTLimiter::getThreshold,	(TTSetterMethod)&TTLimiter::setThreshold);
	registerAttribute(TT("lookahead"),	kTypeUInt32,	&attrLookahead, (TTSetterMethod)&TTLimiter::setLookahead);
	registerAttribute(TT("release"),	kTypeFloat64,	&attrRelease,	(TTSetterMethod)&TTLimiter::setRelease);
	registerAttribute(TT("mode"),		kTypeSymbol,	&attrMode,		(TTSetterMethod)&TTLimiter::setMode);
	registerAttribute(TT("dcBlocker"),	kTypeBoolean,	&attrDCBlocker,	(TTSetterMethod)&TTLimiter::setDCBlocker);

	// register for notifications from the parent class so we can allocate memory as required
	addUpdates(MaxNumChannels);
	// register for notifications from the parent class so we can update the release/recover values
	addUpdates(SampleRate);

	// clear the history
	addMessage(clear);

	// Set Defaults...
	setAttributeValue(kTTSym_maxNumChannels,	initialMaxNumChannels);
	setAttributeValue(TT("threshold"),		0.0);
	setAttributeValue(TT("preamp"),			0.0);
	setAttributeValue(TT("postamp"),		0.0);
	setAttributeValue(TT("lookahead"),		100);
	setAttributeValue(TT("mode"),			TT("exponential"));
	setAttributeValue(TT("release"),		1000.0);
	setAttributeValue(TT("dcBlocker"),		kTTBoolYes);
	setAttributeValue(TT("bypass"),			kTTBoolNo);

	clear();
	setProcessMethod(processAudio);
}

TTLimiter::~TTLimiter()
{
	short i;

	for (i=0; i<mMaxNumChannels; i++)
		delete [] lookaheadBuffer[i];
	delete [] lookaheadBuffer;
	delete [] gain;
}

// TODO: These message receiver args should be reversed -- this is a change that should be applied throughout TTBlue
TTErr TTLimiter::updateMaxNumChannels(const TTValue& oldMaxNumChannels, TTValue&)
{
	TTUInt16	channel;
	TTUInt16	numChannels = oldMaxNumChannels;

	if (lookaheadBuffer) {
		for (channel=0; channel<numChannels; channel++)
			delete [] lookaheadBuffer[channel];
		delete [] lookaheadBuffer;
	}
	delete gain;

	gain = new TTSampleValue[maxBufferSize];
	lookaheadBuffer = new TTSampleValuePtr[mMaxNumChannels];
	for (channel=0; channel<mMaxNumChannels; channel++)
		lookaheadBuffer[channel] = new TTSampleValue[maxBufferSize];

	clear();

	dcBlocker.setAttributeValue(kTTSym_maxNumChannels, mMaxNumChannels);
	preamp.setAttributeValue(kTTSym_maxNumChannels, mMaxNumChannels);

	return kTTErrNone;
}

TTErr TTLimiter::updateSampleRate(const TTValue& oldSampleRate, TTValue&)
{
	setRecover();
	return kTTErrNone;
}

TTErr TTLimiter::setPreamp(TTValue& newValue)
{
//	return preamp.setAttributeValue(TT("gain"), const_cast<TTValue&>(newValue));
	return preamp.setAttributeValue(TT("gain"), newValue);
}

TTErr TTLimiter::getPreamp(TTValue& value)
{
	return preamp.getAttributeValue(TT("gain"), value);
}

TTErr TTLimiter::setPostamp(const TTValue& newValue)
{
	attrPostamp = TTDecibelsToLinearGain(newValue);
	return kTTErrNone;
}

TTErr TTLimiter::getPostamp(TTValue& value)
{
	value = TTLinearGainToDecibels(attrPostamp);
	return kTTErrNone;
}

TTErr TTLimiter::setThreshold(const TTValue& newValue)
{
	attrThreshold = TTDecibelsToLinearGain(newValue);
	return kTTErrNone;
}

TTErr TTLimiter::getThreshold(TTValue& value)
{
	value = TTLinearGainToDecibels(attrThreshold);
	return kTTErrNone;
}

TTErr TTLimiter::setLookahead(TTValue& newValue)
{
	attrLookahead = TTClip(TTUInt32(newValue), TTUInt32(1), maxBufferSize-1);
    lookaheadInv = 1.0 / TTFloat64(attrLookahead);
	return kTTErrNone;
}

TTErr TTLimiter::setRelease(TTValue& newValue)
{
	attrRelease = newValue;
	setRecover();
	return kTTErrNone;
}

TTErr TTLimiter::setMode(TTValue& newValue)
{
	attrMode = newValue;
	if (attrMode == TT("linear"))
		isLinear = true;
	else
		isLinear = false;
	setRecover();
	return kTTErrNone;
}

TTErr TTLimiter::setDCBlocker(TTValue& newValue)
{
	attrDCBlocker = newValue;
	TTBoolean bypassDCBlocker = !attrDCBlocker;

	return dcBlocker.setAttributeValue(TT("bypass"), bypassDCBlocker);
}

TTErr TTLimiter::clear()
{
	TTUInt32	i;
	TTUInt32	channel;

	for (i=0; i<maxBufferSize; i++) {
		for (channel=0; channel < mMaxNumChannels; channel++)
    		lookaheadBuffer[channel][i] = 0.0;
    	gain[i] = 1.0;		// gain is shared across channels
    }

	lookaheadBufferIndex = 0;	// was bp
	last = 1.0;
	setRecover();

	dcBlocker.sendMessage(TT("clear"));
	return kTTErrNone;
}

// set variables related to the time it takes for the limiter to recover from a peak in the audio
// it is based on the release time attr, which is specified in seconds
void TTLimiter::setRecover()
{
	recover = 1000.0 / (attrRelease * sr);
	if (attrMode == TT("linear"))
		recover = recover * 0.5;
	else
		recover = recover * 0.707;
}

TTErr TTLimiter::processAudio(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&	in = inputs->getSignal(0);
	TTAudioSignal&	out = outputs->getSignal(0);
	TTUInt16		vs = in.getVectorSizeAsInt();
	TTUInt16		i, j;
	TTSampleValue	tempSample;
	TTSampleValue	hotSample;
	TTFloat64		maybe,
					curgain,
					newgain,
					inc,
					acc;
	TTInt16			flag,
					lookaheadBufferPlayback,
					ind;
	TTUInt16		numchannels = TTAudioSignal::getMinChannelCount(in, out);
	TTUInt16		channel;

	// Pre-Process the input
	dcBlocker.process(in, out);	// filter out DC-Offsets (unless it is bypassed)
	preamp.process(out, in);		// copy output back to input for the rest of this process

	for (i=0; i<vs; i++) {
		hotSample = 0.0;

		// Analysis Stage ...
		for (channel=0; channel<numchannels; channel++) {
			tempSample = in.mSampleVectors[channel][i];
			lookaheadBuffer[channel][lookaheadBufferIndex] = tempSample * attrPostamp;
			tempSample = fabs(tempSample);
			if (tempSample > hotSample)
				hotSample = tempSample;
		}

		if (isLinear)
			tempSample = last + recover;
		else {
			if (last > 0.01)
				tempSample = last + recover * last;
			else
				tempSample = last + recover;
		}

		if (tempSample > attrThreshold)
			maybe = attrThreshold;
		else
			maybe = tempSample;
		gain[lookaheadBufferIndex] = maybe;

		lookaheadBufferPlayback = lookaheadBufferIndex - attrLookahead;
		if (lookaheadBufferPlayback < 0)
			lookaheadBufferPlayback += attrLookahead;

		// Process Stage ...
		// this ***very slow*** : with a lookahead of 100, and vs = 64, we loop 640 times!
		if (hotSample * maybe > attrThreshold) {
			curgain = attrThreshold / hotSample;
			inc = (attrThreshold - curgain);
			acc = 0;
			flag = 0;
			for (j=0; flag==0 && j<attrLookahead; j++) {
				ind = lookaheadBufferIndex - j;
				if (ind<0)
					ind += maxBufferSize;

				if (isLinear) //TODO: can't we move this condition outside the loop? isLinear won't change during a vs [NP]
					newgain = curgain + inc * acc;
				else
					newgain = curgain + inc * (acc * acc);

				if (newgain < gain[ind])
					gain[ind] = newgain;
				else
					flag = 1;
				acc = acc + lookaheadInv;
			}
		}

		// Actual application of the gain
		for (channel=0; channel<numchannels; channel++) {
			out.mSampleVectors[channel][i] = lookaheadBuffer[channel][lookaheadBufferPlayback] * gain[lookaheadBufferPlayback];
		}

		last = gain[lookaheadBufferIndex];
		lookaheadBufferIndex++;
		if (lookaheadBufferIndex >= attrLookahead)
			lookaheadBufferIndex = 0;
	}
	return kTTErrNone;
}
<commit_msg>TTLimiter: updated for changes to the TTObject API<commit_after>/*
 * TTBlue Limiter Object
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTLimiter.h"

#define thisTTClass			TTLimiter
#define thisTTClassName		"limiter"
#define thisTTClassTags		"audio, processor, dynamics, limiter"

TT_AUDIO_CONSTRUCTOR,
	recover(0.0),
	lookaheadBufferIndex(0),
	lookaheadBuffer(NULL),
	gain(NULL),
	last(0.0),
	dcBlocker(kTTSym_dcblock),
	preamp(kTTSym_gain),
	maxBufferSize(512),
	attrMode(TT("exponential"))
{
	TTUInt16	initialMaxNumChannels = arguments;

	// register our attributes
	registerAttribute(TT("preamp"),		kTypeFloat64,	NULL,			(TTGetterMethod)&TTLimiter::getPreamp,		(TTSetterMethod)&TTLimiter::setPreamp);
	registerAttribute(TT("postamp"),	kTypeFloat64,	&attrPostamp,	(TTGetterMethod)&TTLimiter::getPostamp,		(TTSetterMethod)&TTLimiter::setPostamp);
	registerAttribute(TT("threshold"),	kTypeFloat64,	&attrThreshold,	(TTGetterMethod)&TTLimiter::getThreshold,	(TTSetterMethod)&TTLimiter::setThreshold);
	registerAttribute(TT("lookahead"),	kTypeUInt32,	&attrLookahead, (TTSetterMethod)&TTLimiter::setLookahead);
	registerAttribute(TT("release"),	kTypeFloat64,	&attrRelease,	(TTSetterMethod)&TTLimiter::setRelease);
	registerAttribute(TT("mode"),		kTypeSymbol,	&attrMode,		(TTSetterMethod)&TTLimiter::setMode);
	registerAttribute(TT("dcBlocker"),	kTypeBoolean,	&attrDCBlocker,	(TTSetterMethod)&TTLimiter::setDCBlocker);

	// register for notifications from the parent class so we can allocate memory as required
	addUpdates(MaxNumChannels);
	// register for notifications from the parent class so we can update the release/recover values
	addUpdates(SampleRate);

	// clear the history
	addMessage(clear);

	// Set Defaults...
	setAttributeValue(kTTSym_maxNumChannels,	initialMaxNumChannels);
	setAttributeValue("threshold",				0.0);
	setAttributeValue("preamp",					0.0);
	setAttributeValue("postamp",				0.0);
	setAttributeValue("lookahead",				100);
	setAttributeValue("mode",					"exponential");
	setAttributeValue("release",				1000.0);
	setAttributeValue("dcBlocker",				kTTBoolYes);
	setAttributeValue("bypass",					kTTBoolNo);

	clear();
	setProcessMethod(processAudio);
}

TTLimiter::~TTLimiter()
{
	short i;

	for (i=0; i<mMaxNumChannels; i++)
		delete [] lookaheadBuffer[i];
	delete [] lookaheadBuffer;
	delete [] gain;
}

// TODO: These message receiver args should be reversed -- this is a change that should be applied throughout TTBlue
TTErr TTLimiter::updateMaxNumChannels(const TTValue& oldMaxNumChannels, TTValue&)
{
	TTUInt16	channel;
	TTUInt16	numChannels = oldMaxNumChannels;

	if (lookaheadBuffer) {
		for (channel=0; channel<numChannels; channel++)
			delete [] lookaheadBuffer[channel];
		delete [] lookaheadBuffer;
	}
	delete gain;

	gain = new TTSampleValue[maxBufferSize];
	lookaheadBuffer = new TTSampleValuePtr[mMaxNumChannels];
	for (channel=0; channel<mMaxNumChannels; channel++)
		lookaheadBuffer[channel] = new TTSampleValue[maxBufferSize];

	clear();

	dcBlocker.set(kTTSym_maxNumChannels, mMaxNumChannels);
	preamp.set(kTTSym_maxNumChannels, mMaxNumChannels);

	return kTTErrNone;
}

TTErr TTLimiter::updateSampleRate(const TTValue& oldSampleRate, TTValue&)
{
	setRecover();
	return kTTErrNone;
}

TTErr TTLimiter::setPreamp(TTValue& newValue)
{
	return preamp.set("gain", newValue);
}

TTErr TTLimiter::getPreamp(TTValue& value)
{
	return preamp.get("gain", value);
}

TTErr TTLimiter::setPostamp(const TTValue& newValue)
{
	attrPostamp = TTDecibelsToLinearGain(newValue);
	return kTTErrNone;
}

TTErr TTLimiter::getPostamp(TTValue& value)
{
	value = TTLinearGainToDecibels(attrPostamp);
	return kTTErrNone;
}

TTErr TTLimiter::setThreshold(const TTValue& newValue)
{
	attrThreshold = TTDecibelsToLinearGain(newValue);
	return kTTErrNone;
}

TTErr TTLimiter::getThreshold(TTValue& value)
{
	value = TTLinearGainToDecibels(attrThreshold);
	return kTTErrNone;
}

TTErr TTLimiter::setLookahead(TTValue& newValue)
{
	attrLookahead = TTClip(TTUInt32(newValue), TTUInt32(1), maxBufferSize-1);
    lookaheadInv = 1.0 / TTFloat64(attrLookahead);
	return kTTErrNone;
}

TTErr TTLimiter::setRelease(TTValue& newValue)
{
	attrRelease = newValue;
	setRecover();
	return kTTErrNone;
}

TTErr TTLimiter::setMode(TTValue& newValue)
{
	attrMode = newValue;
	if (attrMode == "linear")
		isLinear = true;
	else
		isLinear = false;
	setRecover();
	return kTTErrNone;
}

TTErr TTLimiter::setDCBlocker(TTValue& newValue)
{
	attrDCBlocker = newValue;
	return dcBlocker.set("bypass", !attrDCBlocker);
}

TTErr TTLimiter::clear()
{
	TTUInt32	i;
	TTUInt32	channel;

	for (i=0; i<maxBufferSize; i++) {
		for (channel=0; channel < mMaxNumChannels; channel++)
    		lookaheadBuffer[channel][i] = 0.0;
    	gain[i] = 1.0;		// gain is shared across channels
    }

	lookaheadBufferIndex = 0;	// was bp
	last = 1.0;
	setRecover();

	dcBlocker.send("clear");
	return kTTErrNone;
}

// set variables related to the time it takes for the limiter to recover from a peak in the audio
// it is based on the release time attr, which is specified in seconds
void TTLimiter::setRecover()
{
	recover = 1000.0 / (attrRelease * sr);
	if (attrMode == "linear")
		recover = recover * 0.5;
	else
		recover = recover * 0.707;
}

TTErr TTLimiter::processAudio(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&	in = inputs->getSignal(0);
	TTAudioSignal&	out = outputs->getSignal(0);
	TTUInt16		vs = in.getVectorSizeAsInt();
	TTUInt16		i, j;
	TTSampleValue	tempSample;
	TTSampleValue	hotSample;
	TTFloat64		maybe,
					curgain,
					newgain,
					inc,
					acc;
	TTInt16			flag,
					lookaheadBufferPlayback,
					ind;
	TTUInt16		numchannels = TTAudioSignal::getMinChannelCount(in, out);
	TTUInt16		channel;

	// Pre-Process the input
	dcBlocker.process(in, out);	// filter out DC-Offsets (unless it is bypassed)
	preamp.process(out, in);		// copy output back to input for the rest of this process

	for (i=0; i<vs; i++) {
		hotSample = 0.0;

		// Analysis Stage ...
		for (channel=0; channel<numchannels; channel++) {
			tempSample = in.mSampleVectors[channel][i];
			lookaheadBuffer[channel][lookaheadBufferIndex] = tempSample * attrPostamp;
			tempSample = fabs(tempSample);
			if (tempSample > hotSample)
				hotSample = tempSample;
		}

		if (isLinear)
			tempSample = last + recover;
		else {
			if (last > 0.01)
				tempSample = last + recover * last;
			else
				tempSample = last + recover;
		}

		if (tempSample > attrThreshold)
			maybe = attrThreshold;
		else
			maybe = tempSample;
		gain[lookaheadBufferIndex] = maybe;

		lookaheadBufferPlayback = lookaheadBufferIndex - attrLookahead;
		if (lookaheadBufferPlayback < 0)
			lookaheadBufferPlayback += attrLookahead;

		// Process Stage ...
		// this ***very slow*** : with a lookahead of 100, and vs = 64, we loop 640 times!
		if (hotSample * maybe > attrThreshold) {
			curgain = attrThreshold / hotSample;
			inc = (attrThreshold - curgain);
			acc = 0;
			flag = 0;
			for (j=0; flag==0 && j<attrLookahead; j++) {
				ind = lookaheadBufferIndex - j;
				if (ind<0)
					ind += maxBufferSize;

				if (isLinear) //TODO: can't we move this condition outside the loop? isLinear won't change during a vs [NP]
					newgain = curgain + inc * acc;
				else
					newgain = curgain + inc * (acc * acc);

				if (newgain < gain[ind])
					gain[ind] = newgain;
				else
					flag = 1;
				acc = acc + lookaheadInv;
			}
		}

		// Actual application of the gain
		for (channel=0; channel<numchannels; channel++) {
			out.mSampleVectors[channel][i] = lookaheadBuffer[channel][lookaheadBufferPlayback] * gain[lookaheadBufferPlayback];
		}

		last = gain[lookaheadBufferIndex];
		lookaheadBufferIndex++;
		if (lookaheadBufferIndex >= attrLookahead)
			lookaheadBufferIndex = 0;
	}
	return kTTErrNone;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPTableToStructuredGrid.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkPTableToStructuredGrid.h"

#include "vtkDataSetAttributes.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTable.h"
#include "vtkStructuredData.h"

static void CopyStructuredData(vtkDataSetAttributes* out, int outExtent[6],
  vtkDataSetAttributes* in, int inExtent[6])
{
  int indims[3];
  indims[0] = inExtent[1] - inExtent[0]+1;
  indims[1] = inExtent[3] - inExtent[2]+1;
  indims[2] = inExtent[5] - inExtent[4]+1;

  int outdims[3];
  outdims[0] = outExtent[1] - outExtent[0]+1;
  outdims[1] = outExtent[3] - outExtent[2]+1;
  outdims[2] = outExtent[5] - outExtent[4]+1;

  int relativeExtent[6];
  relativeExtent[0] = outExtent[0] - inExtent[0];
  relativeExtent[1] = outExtent[1] - inExtent[0];
  relativeExtent[2] = outExtent[2] - inExtent[2];
  relativeExtent[3] = outExtent[3] - inExtent[2];
  relativeExtent[4] = outExtent[4] - inExtent[4];
  relativeExtent[5] = outExtent[5] - inExtent[4];

  for (int zz=relativeExtent[4]; zz <= relativeExtent[5]; zz++)
    {
    for (int yy=relativeExtent[2]; yy <= relativeExtent[3]; yy++)
      {
      for (int xx=relativeExtent[0]; xx <= relativeExtent[1]; xx++)
        {
        int index[3] = {xx, yy, zz};
        int outindex[3] = {xx-relativeExtent[0], yy-relativeExtent[2],
          zz-relativeExtent[4]};
        out->CopyData(in,
          vtkStructuredData::ComputePointId(indims, index),
          vtkStructuredData::ComputePointId(outdims, outindex));
        }
      }
    }

}

vtkStandardNewMacro(vtkPTableToStructuredGrid);
vtkCxxRevisionMacro(vtkPTableToStructuredGrid, "1.1");
vtkCxxSetObjectMacro(vtkPTableToStructuredGrid, Controller,
  vtkMultiProcessController);
//----------------------------------------------------------------------------
vtkPTableToStructuredGrid::vtkPTableToStructuredGrid()
{
  this->Controller = 0;
  this->SetController(vtkMultiProcessController::GetGlobalController());
}

//----------------------------------------------------------------------------
vtkPTableToStructuredGrid::~vtkPTableToStructuredGrid()
{
  this->SetController(0);
}

//----------------------------------------------------------------------------
int vtkPTableToStructuredGrid::RequestData(vtkInformation* request,
    vtkInformationVector** inputVector, vtkInformationVector* outputVector)
{
  int numProcs = this->Controller->GetNumberOfProcesses();
  int myId = this->Controller->GetLocalProcessId();

  if (numProcs <= 1)
    {
    return this->Superclass::RequestData(request, inputVector, outputVector);
    }

  vtkStructuredGrid* output = vtkStructuredGrid::GetData(outputVector, 0);
  vtkTable* input = vtkTable::GetData(inputVector[0], 0);

  int data_valid = 0;
  if (myId == 0)
    {
    // Ensure that extents are valid.
    int num_values = (this->WholeExtent[1] - this->WholeExtent[0] + 1) *
      (this->WholeExtent[3] - this->WholeExtent[2] + 1) *
      (this->WholeExtent[5] - this->WholeExtent[4] + 1);

    if (input->GetNumberOfRows() != num_values)
      {
      vtkErrorMacro("The input table must have exactly " << num_values
        << " rows. Currently it has " << input->GetNumberOfRows() << " rows.");
      }
    else
      {
      data_valid = 1;
      }
    }
  this->Controller->Broadcast(&data_valid, 1, 0);
  if (!data_valid)
    {
    return 0;
    }

  vtkStreamingDemandDrivenPipeline *sddp =
    vtkStreamingDemandDrivenPipeline::SafeDownCast(this->GetExecutive());
  int extent[6];
  sddp->GetOutputInformation(0)->Get(
    vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), extent);

  int *allextents = new int[numProcs*6];
  if (!this->Controller->Gather(extent, allextents, 6, 0))
    {
    vtkErrorMacro("Failed to gather extents.");
    return 0;
    }
  if (myId == 0)
    {
    // Send the relevant rows to each of the processes.
    for (int cc=0; cc < numProcs; cc++)
      {
      int curExtent[6];
      memcpy(curExtent, &allextents[6*cc], 6*sizeof(int));
      vtkIdType numTuples = (curExtent[1]-curExtent[0] + 1) *
        (curExtent[3]-curExtent[2] + 1) *
        (curExtent[5]-curExtent[4] + 1);

      vtkTable* curTable = vtkTable::New();
      curTable->GetRowData()->CopyAllocate(input->GetRowData(), numTuples);
      ::CopyStructuredData(curTable->GetRowData(), curExtent,
        input->GetRowData(), this->WholeExtent);
      if (cc==0)
        {
        this->Superclass::Convert(curTable, output, curExtent);
        }
      else
        {
        this->Controller->Send(curTable, cc, 985723);
        }
      curTable->Delete();
      }
    }
  else
    {
    vtkTable* curTable = vtkTable::New();
    this->Controller->Receive(curTable, 0, 985723);
    this->Superclass::Convert(curTable, output, extent);
    curTable->Delete();
    }
  return 1;
}

//----------------------------------------------------------------------------
void vtkPTableToStructuredGrid::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

<commit_msg>ENH: fixed prinfself<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPTableToStructuredGrid.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkPTableToStructuredGrid.h"

#include "vtkDataSetAttributes.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTable.h"
#include "vtkStructuredData.h"

static void CopyStructuredData(vtkDataSetAttributes* out, int outExtent[6],
  vtkDataSetAttributes* in, int inExtent[6])
{
  int indims[3];
  indims[0] = inExtent[1] - inExtent[0]+1;
  indims[1] = inExtent[3] - inExtent[2]+1;
  indims[2] = inExtent[5] - inExtent[4]+1;

  int outdims[3];
  outdims[0] = outExtent[1] - outExtent[0]+1;
  outdims[1] = outExtent[3] - outExtent[2]+1;
  outdims[2] = outExtent[5] - outExtent[4]+1;

  int relativeExtent[6];
  relativeExtent[0] = outExtent[0] - inExtent[0];
  relativeExtent[1] = outExtent[1] - inExtent[0];
  relativeExtent[2] = outExtent[2] - inExtent[2];
  relativeExtent[3] = outExtent[3] - inExtent[2];
  relativeExtent[4] = outExtent[4] - inExtent[4];
  relativeExtent[5] = outExtent[5] - inExtent[4];

  for (int zz=relativeExtent[4]; zz <= relativeExtent[5]; zz++)
    {
    for (int yy=relativeExtent[2]; yy <= relativeExtent[3]; yy++)
      {
      for (int xx=relativeExtent[0]; xx <= relativeExtent[1]; xx++)
        {
        int index[3] = {xx, yy, zz};
        int outindex[3] = {xx-relativeExtent[0], yy-relativeExtent[2],
          zz-relativeExtent[4]};
        out->CopyData(in,
          vtkStructuredData::ComputePointId(indims, index),
          vtkStructuredData::ComputePointId(outdims, outindex));
        }
      }
    }

}

vtkStandardNewMacro(vtkPTableToStructuredGrid);
vtkCxxRevisionMacro(vtkPTableToStructuredGrid, "1.2");
vtkCxxSetObjectMacro(vtkPTableToStructuredGrid, Controller,
  vtkMultiProcessController);
//----------------------------------------------------------------------------
vtkPTableToStructuredGrid::vtkPTableToStructuredGrid()
{
  this->Controller = 0;
  this->SetController(vtkMultiProcessController::GetGlobalController());
}

//----------------------------------------------------------------------------
vtkPTableToStructuredGrid::~vtkPTableToStructuredGrid()
{
  this->SetController(0);
}

//----------------------------------------------------------------------------
int vtkPTableToStructuredGrid::RequestData(vtkInformation* request,
    vtkInformationVector** inputVector, vtkInformationVector* outputVector)
{
  int numProcs = this->Controller->GetNumberOfProcesses();
  int myId = this->Controller->GetLocalProcessId();

  if (numProcs <= 1)
    {
    return this->Superclass::RequestData(request, inputVector, outputVector);
    }

  vtkStructuredGrid* output = vtkStructuredGrid::GetData(outputVector, 0);
  vtkTable* input = vtkTable::GetData(inputVector[0], 0);

  int data_valid = 0;
  if (myId == 0)
    {
    // Ensure that extents are valid.
    int num_values = (this->WholeExtent[1] - this->WholeExtent[0] + 1) *
      (this->WholeExtent[3] - this->WholeExtent[2] + 1) *
      (this->WholeExtent[5] - this->WholeExtent[4] + 1);

    if (input->GetNumberOfRows() != num_values)
      {
      vtkErrorMacro("The input table must have exactly " << num_values
        << " rows. Currently it has " << input->GetNumberOfRows() << " rows.");
      }
    else
      {
      data_valid = 1;
      }
    }
  this->Controller->Broadcast(&data_valid, 1, 0);
  if (!data_valid)
    {
    return 0;
    }

  vtkStreamingDemandDrivenPipeline *sddp =
    vtkStreamingDemandDrivenPipeline::SafeDownCast(this->GetExecutive());
  int extent[6];
  sddp->GetOutputInformation(0)->Get(
    vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), extent);

  int *allextents = new int[numProcs*6];
  if (!this->Controller->Gather(extent, allextents, 6, 0))
    {
    vtkErrorMacro("Failed to gather extents.");
    return 0;
    }
  if (myId == 0)
    {
    // Send the relevant rows to each of the processes.
    for (int cc=0; cc < numProcs; cc++)
      {
      int curExtent[6];
      memcpy(curExtent, &allextents[6*cc], 6*sizeof(int));
      vtkIdType numTuples = (curExtent[1]-curExtent[0] + 1) *
        (curExtent[3]-curExtent[2] + 1) *
        (curExtent[5]-curExtent[4] + 1);

      vtkTable* curTable = vtkTable::New();
      curTable->GetRowData()->CopyAllocate(input->GetRowData(), numTuples);
      ::CopyStructuredData(curTable->GetRowData(), curExtent,
        input->GetRowData(), this->WholeExtent);
      if (cc==0)
        {
        this->Superclass::Convert(curTable, output, curExtent);
        }
      else
        {
        this->Controller->Send(curTable, cc, 985723);
        }
      curTable->Delete();
      }
    }
  else
    {
    vtkTable* curTable = vtkTable::New();
    this->Controller->Receive(curTable, 0, 985723);
    this->Superclass::Convert(curTable, output, extent);
    curTable->Delete();
    }
  return 1;
}

//----------------------------------------------------------------------------
void vtkPTableToStructuredGrid::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Controller: " << this->Controller << endl;
}

<|endoftext|>


<commit_before>#pragma once

#include <functional>
#include <vector>

#include "base/not_null.hpp"
#include "geometry/named_quantities.hpp"
#include "numerics/double_precision.hpp"
#include "quantities/named_quantities.hpp"
#include "serialization/integrators.pb.h"

namespace principia {

using base::not_null;
using geometry::Instant;
using numerics::DoublePrecision;
using quantities::Time;
using quantities::Variation;

namespace integrators {

// A differential equation of the form q″ = f(q, t).
// |Position| is the type of q.
template<typename Position_>
struct SpecialSecondOrderDifferentialEquation {
  using Position = Position_;
  // The type of Δq.
  using Displacement = Difference<Position>;
  // The type of q′.
  using Velocity = Variation<Position>;
  // The type of q″.
  using Acceleration = Variation<Velocity>;
  using RightHandSideComputation =
      std::function<
          void(Instant const& t,
               std::vector<Position> const& positions,
               not_null<std::vector<Acceleration>*> const accelerations)>;

  struct SystemState {
    std::vector<DoublePrecision<Position>> positions;
    std::vector<DoublePrecision<Velocity>> velocities;
    DoublePrecision<Instant> time;

    void WriteToMessage(
        not_null<serialization::SystemState*> const message) const;
    static SystemState ReadFromMessage(
        serialization::SystemState const& message);
  };

  struct SystemStateError {
    std::vector<Displacement> position_error;
    std::vector<Velocity> velocity_error;
  };

  // A functor that computes f(q, t) and stores it in |*accelerations|.
  // This functor must be called with |accelerations->size()| equal to
  // |positions->size()|, but there is no requirement on the values in
  // |*acceleration|.
  RightHandSideComputation compute_acceleration;
};

// An initial value problem, together with a final time for the solution
// and a callback for processing solution points.
template<typename ODE>
struct IntegrationProblem {
  ODE equation;
  typename ODE::SystemState const* initial_state;
  Instant t_final;
  std::function<void(typename ODE::SystemState const& state)> append_state;
};

// Settings for for adaptive step size integration.
template<typename ODE>
struct AdaptiveStepSize {
  using ToleranceToErrorRatio =
      std::function<
          double(Time const& current_step_size,
                 typename ODE::SystemStateError const& error)>;
  // The first time step tried by the integrator. It must have the same sign as
  // |problem.t_final - initial_state.time.value|.
  Time first_time_step;
  // This number must be in ]0, 1[.  Higher values increase the chance of step
  // rejection, lower values yield smaller steps.
  double safety_factor;
  // This functor is called at each step, with the |current_step_size| used by
  // the integrator and the estimated |error| on that step.  It returns the
  // ratio of a tolerance to some norm of the error.  The step is recomputed
  // with a smaller step size if the result is less than 1, and accepted
  // otherwise.
  // In both cases, the new step size is chosen so as to try and make the result
  // of the next call to |tolerance_to_error_ratio| close to |safety_factor|.
  ToleranceToErrorRatio tolerance_to_error_ratio;
};

// A base class for integrators.
template<typename DifferentialEquation>
class Integrator {
 public:
  using ODE = DifferentialEquation;
};

// An integrator using a fixed step size.
template<typename DifferentialEquation>
class FixedStepSizeIntegrator : public Integrator<DifferentialEquation> {
 public:
  using ODE = DifferentialEquation;
  // The last call to |problem.append_state| has a |state.time.value| equal to
  // the unique |Instant| of the form |problem.t_final + n * step| in
  // [problem.t_final, problem.t_final + step[.
  // |problem.append_state| will be called with |state.time.values|s at
  // intervals differing from |step| by at most one ULP.
  virtual void Solve(IntegrationProblem<ODE> const& problem,
                     Time const& step) const = 0;

  void WriteToMessage(
      not_null<serialization::FixedStepSizeIntegrator*> const message) const;
  static FixedStepSizeIntegrator const& ReadFromMessage(
      serialization::FixedStepSizeIntegrator const& message);

 protected:
  explicit FixedStepSizeIntegrator(
      serialization::FixedStepSizeIntegrator::Kind const kind);

 private:
  serialization::FixedStepSizeIntegrator::Kind const kind_;
};

// An integrator using a fixed step size.
template<typename DifferentialEquation>
class AdaptiveStepSizeIntegrator : public Integrator<DifferentialEquation> {
 public:
  using ODE = DifferentialEquation;
  // The last call to |problem.append_state| will have
  // |state.time.value == problem.t_final|.
  virtual void Solve(IntegrationProblem<ODE> const& problem,
                     AdaptiveStepSize<ODE> const& adaptive_step_size) const = 0;

  void WriteToMessage(
      not_null<serialization::AdaptiveStepSizeIntegrator*> const message) const;
  static AdaptiveStepSizeIntegrator const& ReadFromMessage(
      serialization::AdaptiveStepSizeIntegrator const& message);

 protected:
  explicit AdaptiveStepSizeIntegrator(
      serialization::AdaptiveStepSizeIntegrator::Kind const kind);

 private:
  serialization::AdaptiveStepSizeIntegrator::Kind const kind_;
};

}  // namespace integrators
}  // namespace principia

#include "integrators/ordinary_differential_equations_body.hpp"
<commit_msg>fix the contract too<commit_after>#pragma once

#include <functional>
#include <vector>

#include "base/not_null.hpp"
#include "geometry/named_quantities.hpp"
#include "numerics/double_precision.hpp"
#include "quantities/named_quantities.hpp"
#include "serialization/integrators.pb.h"

namespace principia {

using base::not_null;
using geometry::Instant;
using numerics::DoublePrecision;
using quantities::Time;
using quantities::Variation;

namespace integrators {

// A differential equation of the form q″ = f(q, t).
// |Position| is the type of q.
template<typename Position_>
struct SpecialSecondOrderDifferentialEquation {
  using Position = Position_;
  // The type of Δq.
  using Displacement = Difference<Position>;
  // The type of q′.
  using Velocity = Variation<Position>;
  // The type of q″.
  using Acceleration = Variation<Velocity>;
  using RightHandSideComputation =
      std::function<
          void(Instant const& t,
               std::vector<Position> const& positions,
               not_null<std::vector<Acceleration>*> const accelerations)>;

  struct SystemState {
    std::vector<DoublePrecision<Position>> positions;
    std::vector<DoublePrecision<Velocity>> velocities;
    DoublePrecision<Instant> time;

    void WriteToMessage(
        not_null<serialization::SystemState*> const message) const;
    static SystemState ReadFromMessage(
        serialization::SystemState const& message);
  };

  struct SystemStateError {
    std::vector<Displacement> position_error;
    std::vector<Velocity> velocity_error;
  };

  // A functor that computes f(q, t) and stores it in |*accelerations|.
  // This functor must be called with |accelerations->size()| equal to
  // |positions->size()|, but there is no requirement on the values in
  // |*acceleration|.
  RightHandSideComputation compute_acceleration;
};

// An initial value problem, together with a final time for the solution
// and a callback for processing solution points.
template<typename ODE>
struct IntegrationProblem {
  ODE equation;
  typename ODE::SystemState const* initial_state;
  Instant t_final;
  std::function<void(typename ODE::SystemState const& state)> append_state;
};

// Settings for for adaptive step size integration.
template<typename ODE>
struct AdaptiveStepSize {
  using ToleranceToErrorRatio =
      std::function<
          double(Time const& current_step_size,
                 typename ODE::SystemStateError const& error)>;
  // The first time step tried by the integrator. It must have the same sign as
  // |problem.t_final - initial_state.time.value|.
  Time first_time_step;
  // This number must be in ]0, 1[.  Higher values increase the chance of step
  // rejection, lower values yield smaller steps.
  double safety_factor;
  // This functor is called at each step, with the |current_step_size| used by
  // the integrator and the estimated |error| on that step.  It returns the
  // ratio of a tolerance to some norm of the error.  The step is recomputed
  // with a smaller step size if the result is less than 1, and accepted
  // otherwise.
  // In both cases, the new step size is chosen so as to try and make the result
  // of the next call to |tolerance_to_error_ratio| close to |safety_factor|.
  ToleranceToErrorRatio tolerance_to_error_ratio;
};

// A base class for integrators.
template<typename DifferentialEquation>
class Integrator {
 public:
  using ODE = DifferentialEquation;
};

// An integrator using a fixed step size.
template<typename DifferentialEquation>
class FixedStepSizeIntegrator : public Integrator<DifferentialEquation> {
 public:
  using ODE = DifferentialEquation;
  // The last call to |problem.append_state| has a |state.time.value| equal to
  // the unique |Instant| of the form |problem.t_final + n * step| in
  // ]problem.t_final - step, problem.t_final].
  // |problem.append_state| will be called with |state.time.values|s at
  // intervals differing from |step| by at most one ULP.
  virtual void Solve(IntegrationProblem<ODE> const& problem,
                     Time const& step) const = 0;

  void WriteToMessage(
      not_null<serialization::FixedStepSizeIntegrator*> const message) const;
  static FixedStepSizeIntegrator const& ReadFromMessage(
      serialization::FixedStepSizeIntegrator const& message);

 protected:
  explicit FixedStepSizeIntegrator(
      serialization::FixedStepSizeIntegrator::Kind const kind);

 private:
  serialization::FixedStepSizeIntegrator::Kind const kind_;
};

// An integrator using a fixed step size.
template<typename DifferentialEquation>
class AdaptiveStepSizeIntegrator : public Integrator<DifferentialEquation> {
 public:
  using ODE = DifferentialEquation;
  // The last call to |problem.append_state| will have
  // |state.time.value == problem.t_final|.
  virtual void Solve(IntegrationProblem<ODE> const& problem,
                     AdaptiveStepSize<ODE> const& adaptive_step_size) const = 0;

  void WriteToMessage(
      not_null<serialization::AdaptiveStepSizeIntegrator*> const message) const;
  static AdaptiveStepSizeIntegrator const& ReadFromMessage(
      serialization::AdaptiveStepSizeIntegrator const& message);

 protected:
  explicit AdaptiveStepSizeIntegrator(
      serialization::AdaptiveStepSizeIntegrator::Kind const kind);

 private:
  serialization::AdaptiveStepSizeIntegrator::Kind const kind_;
};

}  // namespace integrators
}  // namespace principia

#include "integrators/ordinary_differential_equations_body.hpp"
<|endoftext|>


<commit_before>// ChiCheCanvas.cpp

#include "ChiChe.h"

using namespace ChiChe;

int Canvas::attributeList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };

//=====================================================================================
Canvas::Canvas( wxWindow* parent ) : wxGLCanvas( parent, wxID_ANY, attributeList )
{
	context = 0;

	mousePos.x = 0;
	mousePos.y = 0;

	hitBuffer = 0;
	hitBufferSize = 0;

	lastFrameTime = -1;
	frameRate = 60.0;

	Bind( wxEVT_PAINT, &Canvas::OnPaint, this );
	Bind( wxEVT_SIZE, &Canvas::OnSize, this );
	Bind( wxEVT_MOUSEWHEEL, &Canvas::OnMouseWheel, this );
	Bind( wxEVT_LEFT_DOWN, &Canvas::OnMouseLeftDown, this );
	Bind( wxEVT_RIGHT_DOWN, &Canvas::OnMouseRightDown, this );
	Bind( wxEVT_MOTION, &Canvas::OnMouseMotion, this );
}

//=====================================================================================
/*virtual*/ Canvas::~Canvas( void )
{
	delete context;
}

//=====================================================================================
void Canvas::BindContext( void )
{
	if( !context )
		context = new wxGLContext( this );

	SetCurrent( *context );
}

//=====================================================================================
double Canvas::FrameRate( void )
{
	return frameRate;
}

//=====================================================================================
void Canvas::OnPaint( wxPaintEvent& event )
{
	PreRender( GL_RENDER );

	Client* client = wxGetApp().GetClient();
	if( client )
	{
		// Approximate the frame-rate this frame as the frame-rate last frame.
		wxLongLong thisFrameTime = wxGetLocalTimeMillis();
		if( lastFrameTime != -1 )
		{
			wxLongLong deltaTime = thisFrameTime - lastFrameTime;
			double frameTime = deltaTime.ToDouble() / 1000.0;
			frameRate = 1.0 / frameTime;
		}
		lastFrameTime = thisFrameTime;

		// Ask the client to render for us.
		client->Render( GL_RENDER );
	}

	PostRender( GL_RENDER );
}

//=====================================================================================
void Canvas::PreRender( GLenum renderMode )
{
	BindContext();

	glClearColor( 0.f, 0.f, 0.f, 1.f );
	glEnable( GL_DEPTH_TEST );
	glEnable( GL_LINE_SMOOTH );
	glEnable( GL_BLEND );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE );
	glShadeModel( GL_SMOOTH );

	if( renderMode == GL_SELECT )
	{
		hitBufferSize = 512;
		hitBuffer = new unsigned int[ hitBufferSize ];
		glSelectBuffer( hitBufferSize, hitBuffer );

		glRenderMode( GL_SELECT );
		glInitNames();
	}

	glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

	wxPoint* pickingPoint = 0;
	if( renderMode == GL_SELECT )
		pickingPoint = &mousePos;
	camera.LoadViewingMatrices( pickingPoint );
}

//=====================================================================================
void Canvas::PostRender( GLenum renderMode )
{
	glFlush();

	if( renderMode == GL_SELECT )
	{
		int hitCount = glRenderMode( GL_RENDER );

		Client* client = wxGetApp().GetClient();
		if( client )
			client->ProcessHitList( hitBuffer, hitBufferSize, hitCount );

		delete[] hitBuffer;
		hitBuffer = 0;
		hitBufferSize = 0;
	}
	else if( renderMode == GL_RENDER )
	{
		SwapBuffers();
	}
}

//=====================================================================================
void Canvas::OnSize( wxSizeEvent& event )
{
	BindContext();
	wxSize size = event.GetSize();
	glViewport( 0, 0, size.GetWidth(), size.GetHeight() );
	double aspectRatio = double( size.GetWidth() ) / double( size.GetHeight() );
	camera.SetAspectRatio( aspectRatio );
	Refresh();
}

//=====================================================================================
void Canvas::OnMouseWheel( wxMouseEvent& event )
{
	double wheelDelta = event.GetWheelDelta();
	double wheelRotation = event.GetWheelRotation();
	double wheelIncrements = wheelRotation / wheelDelta;
	double zoomPercentagePerIncrement = 0.1;
	double zoomPercentage = 1.0 + wheelIncrements * zoomPercentagePerIncrement;
	double minimumFocalLength = 5.0;
	double maximumFocalLength = 100.0;
	camera.Zoom( zoomPercentage, minimumFocalLength, maximumFocalLength );
	Refresh();
}

//=====================================================================================
void Canvas::OnMouseLeftDown( wxMouseEvent& event )
{
	mousePos = event.GetPosition();
}

//=====================================================================================
void Canvas::OnMouseRightDown( wxMouseEvent& event )
{
	mousePos = event.GetPosition();

	Client* client = wxGetApp().GetClient();
	if( client )
	{
		PreRender( GL_SELECT );
		client->Render( GL_SELECT );
		PostRender( GL_SELECT );
	}
}

//=====================================================================================
void Canvas::OnMouseMotion( wxMouseEvent& event )
{
	if( event.LeftIsDown() )
	{
		wxPoint mouseDelta = event.GetPosition() - mousePos;
		mousePos = event.GetPosition();

		c3ga::vectorE3GA eye = camera.GetEye();

		c3ga::vectorE3GA xAxis, yAxis, zAxis;
		camera.CalcPanFrame( xAxis, yAxis, zAxis );

		double unitsPerPixel = 0.2;

		c3ga::vectorE3GA delta;
		delta.set( c3ga::vectorE3GA::coord_e1_e2_e3, unitsPerPixel * -double( mouseDelta.x ), unitsPerPixel * double( mouseDelta.y ), 0.0 );
		delta = c3ga::gp( xAxis, delta.get_e1() ) + c3ga::gp( yAxis, delta.get_e2() ) + c3ga::gp( zAxis, delta.get_e3() );
		camera.Move( delta, true );

		c3ga::vectorE3GA lookVec = c3ga::unit( camera.GetFocus() - camera.GetEye() );
		double angle = acos( lookVec.get_e2() );
		if( angle < M_PI / 2.0 || angle > M_PI * 0.95 )
			camera.SetEye( eye );
		else
			Refresh();
	}
}

//=====================================================================================
Canvas::Camera::Camera( void )
{
	focus.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 0.0, 0.0 );
	eye.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 20.0, -50.0 );
	up.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 1.0, 0.0 );

	foviAngle = 60.0;
	aspectRatio = 1.0;
}

//=====================================================================================
Canvas::Camera::~Camera( void )
{
}

//=====================================================================================
void Canvas::Camera::Zoom( double zoomPercentage, double minimumFocalLength, double maximumFocalLength )
{
	c3ga::vectorE3GA originalEye = eye;
	c3ga::vectorE3GA lookVec = focus - eye;
	lookVec = c3ga::gp( lookVec, zoomPercentage );
	eye = focus - lookVec;
	double focalLength = FocalLength();
	if( focalLength < minimumFocalLength || focalLength > maximumFocalLength )
		eye = originalEye;
}

//=====================================================================================
double Canvas::Camera::FocalLength( void )
{
	c3ga::vectorE3GA lookVec = focus - eye;
	return c3ga::norm( lookVec );
}

//=====================================================================================
void Canvas::Camera::Move( const c3ga::vectorE3GA& delta, bool maintainFocalLength /*= true*/ )
{
	double oldFocalLength = FocalLength();
	eye = eye + delta;
	if( maintainFocalLength )
	{
		double newFocalLength = FocalLength();
		double zoomPercentage = oldFocalLength / newFocalLength;
		Zoom( zoomPercentage, 0.0, 1000.0 );
	}
}

//=====================================================================================
void Canvas::Camera::CalcPanFrame( c3ga::vectorE3GA& xAxis, c3ga::vectorE3GA& yAxis, c3ga::vectorE3GA& zAxis )
{
	// This should create a right-handed system.
	c3ga::vectorE3GA lookVec = focus - eye;
	zAxis = c3ga::unit( c3ga::negate( lookVec ) );
	yAxis = c3ga::unit( c3ga::lc( lookVec, c3ga::op( lookVec, up ) ) );
	xAxis = c3ga::gp( c3ga::op( zAxis, yAxis ), c3ga::I3 );
}

//=====================================================================================
void Canvas::Camera::LoadViewingMatrices( wxPoint* pickingPoint /*= 0*/ )
{
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	if( pickingPoint )
	{
		GLint viewport[4];
		glGetIntegerv( GL_VIEWPORT, viewport );
		GLdouble x = pickingPoint->x;
		GLdouble y = GLdouble( viewport[3] ) - GLdouble( pickingPoint->y );
		GLdouble w = 2.0;
		GLdouble h = 2.0;
		gluPickMatrix( x, y, w, h, viewport );
	}
	gluPerspective( foviAngle, aspectRatio, 1.0, 1000.0 );

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	gluLookAt( eye.get_e1(), eye.get_e2(), eye.get_e3(),
				focus.get_e1(), focus.get_e2(), focus.get_e3(),
				up.get_e1(), up.get_e2(), up.get_e3() );
}

//=====================================================================================
void Canvas::Camera::SetAspectRatio( double aspectRatio )
{
	this->aspectRatio = aspectRatio;
}

//=====================================================================================
double Canvas::Camera::GetAspectRatio( void )
{
	return aspectRatio;
}

//=====================================================================================
const c3ga::vectorE3GA& Canvas::Camera::GetEye( void )
{
	return eye;
}

//=====================================================================================
void Canvas::Camera::SetEye( const c3ga::vectorE3GA& eye )
{
	this->eye = eye;
}

//=====================================================================================
const c3ga::vectorE3GA& Canvas::Camera::GetFocus( void )
{
	return focus;
}

//=====================================================================================
void Canvas::Camera::SetFocus( const c3ga::vectorE3GA& focus )
{
	this->focus = focus;
}

// ChiCheCanvas.cpp<commit_msg>set focus on click so that we get mouse wheel events<commit_after>// ChiCheCanvas.cpp

#include "ChiChe.h"

using namespace ChiChe;

int Canvas::attributeList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };

//=====================================================================================
Canvas::Canvas( wxWindow* parent ) : wxGLCanvas( parent, wxID_ANY, attributeList )
{
	context = 0;

	mousePos.x = 0;
	mousePos.y = 0;

	hitBuffer = 0;
	hitBufferSize = 0;

	lastFrameTime = -1;
	frameRate = 60.0;

	Bind( wxEVT_PAINT, &Canvas::OnPaint, this );
	Bind( wxEVT_SIZE, &Canvas::OnSize, this );
	Bind( wxEVT_MOUSEWHEEL, &Canvas::OnMouseWheel, this );
	Bind( wxEVT_LEFT_DOWN, &Canvas::OnMouseLeftDown, this );
	Bind( wxEVT_RIGHT_DOWN, &Canvas::OnMouseRightDown, this );
	Bind( wxEVT_MOTION, &Canvas::OnMouseMotion, this );
}

//=====================================================================================
/*virtual*/ Canvas::~Canvas( void )
{
	delete context;
}

//=====================================================================================
void Canvas::BindContext( void )
{
	if( !context )
		context = new wxGLContext( this );

	SetCurrent( *context );
}

//=====================================================================================
double Canvas::FrameRate( void )
{
	return frameRate;
}

//=====================================================================================
void Canvas::OnPaint( wxPaintEvent& event )
{
	PreRender( GL_RENDER );

	Client* client = wxGetApp().GetClient();
	if( client )
	{
		// Approximate the frame-rate this frame as the frame-rate last frame.
		wxLongLong thisFrameTime = wxGetLocalTimeMillis();
		if( lastFrameTime != -1 )
		{
			wxLongLong deltaTime = thisFrameTime - lastFrameTime;
			double frameTime = deltaTime.ToDouble() / 1000.0;
			frameRate = 1.0 / frameTime;
		}
		lastFrameTime = thisFrameTime;

		// Ask the client to render for us.
		client->Render( GL_RENDER );
	}

	PostRender( GL_RENDER );
}

//=====================================================================================
void Canvas::PreRender( GLenum renderMode )
{
	BindContext();

	glClearColor( 0.f, 0.f, 0.f, 1.f );
	glEnable( GL_DEPTH_TEST );
	glEnable( GL_LINE_SMOOTH );
	glEnable( GL_BLEND );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE );
	glShadeModel( GL_SMOOTH );

	if( renderMode == GL_SELECT )
	{
		hitBufferSize = 512;
		hitBuffer = new unsigned int[ hitBufferSize ];
		glSelectBuffer( hitBufferSize, hitBuffer );

		glRenderMode( GL_SELECT );
		glInitNames();
	}

	glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

	wxPoint* pickingPoint = 0;
	if( renderMode == GL_SELECT )
		pickingPoint = &mousePos;
	camera.LoadViewingMatrices( pickingPoint );
}

//=====================================================================================
void Canvas::PostRender( GLenum renderMode )
{
	glFlush();

	if( renderMode == GL_SELECT )
	{
		int hitCount = glRenderMode( GL_RENDER );

		Client* client = wxGetApp().GetClient();
		if( client )
			client->ProcessHitList( hitBuffer, hitBufferSize, hitCount );

		delete[] hitBuffer;
		hitBuffer = 0;
		hitBufferSize = 0;
	}
	else if( renderMode == GL_RENDER )
	{
		SwapBuffers();
	}
}

//=====================================================================================
void Canvas::OnSize( wxSizeEvent& event )
{
	BindContext();
	wxSize size = event.GetSize();
	glViewport( 0, 0, size.GetWidth(), size.GetHeight() );
	double aspectRatio = double( size.GetWidth() ) / double( size.GetHeight() );
	camera.SetAspectRatio( aspectRatio );
	Refresh();
}

//=====================================================================================
void Canvas::OnMouseWheel( wxMouseEvent& event )
{
	double wheelDelta = event.GetWheelDelta();
	double wheelRotation = event.GetWheelRotation();
	double wheelIncrements = wheelRotation / wheelDelta;
	double zoomPercentagePerIncrement = 0.1;
	double zoomPercentage = 1.0 + wheelIncrements * zoomPercentagePerIncrement;
	double minimumFocalLength = 5.0;
	double maximumFocalLength = 100.0;
	camera.Zoom( zoomPercentage, minimumFocalLength, maximumFocalLength );
	Refresh();
}

//=====================================================================================
void Canvas::OnMouseLeftDown( wxMouseEvent& event )
{
	SetFocus();

	mousePos = event.GetPosition();
}

//=====================================================================================
void Canvas::OnMouseRightDown( wxMouseEvent& event )
{
	mousePos = event.GetPosition();

	Client* client = wxGetApp().GetClient();
	if( client )
	{
		PreRender( GL_SELECT );
		client->Render( GL_SELECT );
		PostRender( GL_SELECT );
	}
}

//=====================================================================================
void Canvas::OnMouseMotion( wxMouseEvent& event )
{
	if( event.LeftIsDown() )
	{
		wxPoint mouseDelta = event.GetPosition() - mousePos;
		mousePos = event.GetPosition();

		c3ga::vectorE3GA eye = camera.GetEye();

		c3ga::vectorE3GA xAxis, yAxis, zAxis;
		camera.CalcPanFrame( xAxis, yAxis, zAxis );

		double unitsPerPixel = 0.2;

		c3ga::vectorE3GA delta;
		delta.set( c3ga::vectorE3GA::coord_e1_e2_e3, unitsPerPixel * -double( mouseDelta.x ), unitsPerPixel * double( mouseDelta.y ), 0.0 );
		delta = c3ga::gp( xAxis, delta.get_e1() ) + c3ga::gp( yAxis, delta.get_e2() ) + c3ga::gp( zAxis, delta.get_e3() );
		camera.Move( delta, true );

		c3ga::vectorE3GA lookVec = c3ga::unit( camera.GetFocus() - camera.GetEye() );
		double angle = acos( lookVec.get_e2() );
		if( angle < M_PI / 2.0 || angle > M_PI * 0.95 )
			camera.SetEye( eye );
		else
			Refresh();
	}
}

//=====================================================================================
Canvas::Camera::Camera( void )
{
	focus.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 0.0, 0.0 );
	eye.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 20.0, -50.0 );
	up.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 1.0, 0.0 );

	foviAngle = 60.0;
	aspectRatio = 1.0;
}

//=====================================================================================
Canvas::Camera::~Camera( void )
{
}

//=====================================================================================
void Canvas::Camera::Zoom( double zoomPercentage, double minimumFocalLength, double maximumFocalLength )
{
	c3ga::vectorE3GA originalEye = eye;
	c3ga::vectorE3GA lookVec = focus - eye;
	lookVec = c3ga::gp( lookVec, zoomPercentage );
	eye = focus - lookVec;
	double focalLength = FocalLength();
	if( focalLength < minimumFocalLength || focalLength > maximumFocalLength )
		eye = originalEye;
}

//=====================================================================================
double Canvas::Camera::FocalLength( void )
{
	c3ga::vectorE3GA lookVec = focus - eye;
	return c3ga::norm( lookVec );
}

//=====================================================================================
void Canvas::Camera::Move( const c3ga::vectorE3GA& delta, bool maintainFocalLength /*= true*/ )
{
	double oldFocalLength = FocalLength();
	eye = eye + delta;
	if( maintainFocalLength )
	{
		double newFocalLength = FocalLength();
		double zoomPercentage = oldFocalLength / newFocalLength;
		Zoom( zoomPercentage, 0.0, 1000.0 );
	}
}

//=====================================================================================
void Canvas::Camera::CalcPanFrame( c3ga::vectorE3GA& xAxis, c3ga::vectorE3GA& yAxis, c3ga::vectorE3GA& zAxis )
{
	// This should create a right-handed system.
	c3ga::vectorE3GA lookVec = focus - eye;
	zAxis = c3ga::unit( c3ga::negate( lookVec ) );
	yAxis = c3ga::unit( c3ga::lc( lookVec, c3ga::op( lookVec, up ) ) );
	xAxis = c3ga::gp( c3ga::op( zAxis, yAxis ), c3ga::I3 );
}

//=====================================================================================
void Canvas::Camera::LoadViewingMatrices( wxPoint* pickingPoint /*= 0*/ )
{
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	if( pickingPoint )
	{
		GLint viewport[4];
		glGetIntegerv( GL_VIEWPORT, viewport );
		GLdouble x = pickingPoint->x;
		GLdouble y = GLdouble( viewport[3] ) - GLdouble( pickingPoint->y );
		GLdouble w = 2.0;
		GLdouble h = 2.0;
		gluPickMatrix( x, y, w, h, viewport );
	}
	gluPerspective( foviAngle, aspectRatio, 1.0, 1000.0 );

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	gluLookAt( eye.get_e1(), eye.get_e2(), eye.get_e3(),
				focus.get_e1(), focus.get_e2(), focus.get_e3(),
				up.get_e1(), up.get_e2(), up.get_e3() );
}

//=====================================================================================
void Canvas::Camera::SetAspectRatio( double aspectRatio )
{
	this->aspectRatio = aspectRatio;
}

//=====================================================================================
double Canvas::Camera::GetAspectRatio( void )
{
	return aspectRatio;
}

//=====================================================================================
const c3ga::vectorE3GA& Canvas::Camera::GetEye( void )
{
	return eye;
}

//=====================================================================================
void Canvas::Camera::SetEye( const c3ga::vectorE3GA& eye )
{
	this->eye = eye;
}

//=====================================================================================
const c3ga::vectorE3GA& Canvas::Camera::GetFocus( void )
{
	return focus;
}

//=====================================================================================
void Canvas::Camera::SetFocus( const c3ga::vectorE3GA& focus )
{
	this->focus = focus;
}

// ChiCheCanvas.cpp<|endoftext|>