//----------------------------------------------------------------------------
void BouncingSpheres::CreateScene ()
{
    CreateBalls();
    CreateFloor();
    CreateBackWall();
    CreateSideWall1();
    CreateSideWall2();

    // ** layout of scene graph **
    // scene
    //     room
    //         backwall
    //         floor
    //         sidewall1
    //         sidewall2
    //     balls

    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    Node* room = new0 Node();
    room->AttachChild(mFloor);
    room->AttachChild(mSideWall1);
    room->AttachChild(mSideWall2);
    room->AttachChild(mBackWall);
    mScene->AttachChild(room);

    Node* ballRoot = new0 Node();
    int i;
    for (i = 0; i < NUM_BALLS; ++i)
    {
        ballRoot->AttachChild(mBallNodes[i]);
    }
    mScene->AttachChild(ballRoot);

    // The balls are constrained to bounce around in a rectangular solid
    // region.  The six defining planes are defined to be immovable rigid
    // bodies.  The boundaries are parallel to coordinate axes and pass
    // through the points indicated by the value other than +-100.  That is,
    // the back wall is at x = 1, the left wall is at y = 2, the floor is at
    // z = 1, the right wall is at y = 15, the ceiling is at z = 17, and the
    // front wall is at x = 9.  The ceiling and front wall are invisible
    // objects (not rendered), but you will see balls bouncing against it
    // and reflecting away from it towards the back wall.
    mBoundaryLocations[0] = Vector3f(1.0f, -100.0f, -100.0f);
    mBoundaryNormals[0] = Vector3f(1.0f, 0.0f, 0.0f);
    mBoundaryLocations[1] = Vector3f(-100.0f, 2.0f, -100.0f);
    mBoundaryNormals[1] = Vector3f(0.0f, 1.0f, 0.0f);
    mBoundaryLocations[2] = Vector3f(-100.0f, -100.0f, 1.0f);
    mBoundaryNormals[2] = Vector3f(0.0f, 0.0f, 1.0f);
    mBoundaryLocations[3] = Vector3f(100.0f, 15.0f, 100.0f);
    mBoundaryNormals[3] = Vector3f(0.0f, -1.0f, 0.0f);
    mBoundaryLocations[4] = Vector3f(100.0f, 100.0f, 17.0f);
    mBoundaryNormals[4] = Vector3f(0.0f, 0.0f, -1.0f);
    mBoundaryLocations[5] = Vector3f(8.0f, 100.0f, 100.0f);
    mBoundaryNormals[5] = Vector3f(-1.0f, 0.0f, 0.0f);
    for (i = 0; i < 6; ++i)
    {
        mBoundaries[i].SetMass(0.0f);
        mBoundaries[i].SetPosition(mBoundaryLocations[i]);
    }
}
// Creates a physics world and lays outt he
void LiquidFunScene::LayoutLevel(int level) {
  // Scale the dimensions of the world to fit the view.
  const CCSize viewSize = CCDirector::sharedDirector()->getVisibleSize();
  const float aspectRatio = viewSize.width / viewSize.height;
  m_worldExtents.x = k_worldWidth;
  m_worldExtents.y = k_worldWidth / aspectRatio;
  m_worldExtentMin = b2Vec2Min(m_worldExtents);
  m_worldExtentMax = b2Vec2Max(m_worldExtents);
  m_worldExtentsInWalls = m_worldExtents;
  m_worldOffsetInWalls.Set(0.0f, 0.0f);

  // Create a world.
  m_world = new b2World(k_gravity);
  m_world->SetParticleRadius(m_worldExtentMin * k_particleSize);
  m_world->SetParticleDamping(0.2f);

  // Enable the Box2D rendering layer.
  Box2DGLESDebugDrawLayer* box2dLayer = new Box2DGLESDebugDrawLayer(
    m_world, b2Vec2Min(b2Vec2(viewSize.width / m_worldExtents.x,
                              viewSize.height / m_worldExtents.y)));
  box2dLayer->init();
  addChild(box2dLayer);
  GLESDebugDraw* const debugDraw = box2dLayer->GetGLESDebugDraw();
  // Turn off AABB drawing.
  debugDraw->SetFlags(debugDraw->GetFlags() & ~b2Draw::e_aabbBit);
  // Render particles as solid circles.
  debugDraw->SetSolidParticlesEnable(true);

  // Create boundaries
  CreateWalls();
  CreateBalls(5, 0.075f);
  CreateBlockOfParticles();

  // Define map-specific stuff
  switch (level) {
    case 0: {
      // Add an emitter in the middle
      static const float k_colorCycleRate = 5.0f;
      std::vector<b2ParticleColor> colors;
      colors.push_back(b2ParticleColor(0xff, 0x00, 0x00, 0xff));
      colors.push_back(b2ParticleColor(0xff, 0xff, 0xff, 0xff));
      colors.push_back(b2ParticleColor(0x00, 0x00, 0xff, 0xff));
      colors.push_back(b2ParticleColor(0x00, 0xff, 0x00, 0xff));
      colors.push_back(b2ParticleColor(0x22, 0xff, 0x44, 0xff));
      AddEmitter(ConvertRelativePositionToWorld(b2Vec2(0.5f, 0.1f)),
                 colors, k_colorCycleRate);

      // Add a kill field to the bottom right of the screen.
      b2CircleShape circle;
      circle.m_radius = m_worldExtentMax * 0.025f;
      b2Transform circleLocationSize;
      circleLocationSize.SetIdentity();
      circleLocationSize.Set(ConvertRelativePositionToWorld(
          b2Vec2(0.8f, 0.9f)), 0.0f);
      AddParticleKillField(circleLocationSize, circle, sizeof(circle));
      break;
    }
    default:
      CCLOG("ERROR: Invalid level %d defined.", level);
      break;
  }
}