/**
   * This adds any actor to the world that we are adding programmatically Currently lights must be
   * loaded this way. That will change in later versions.
   *
   * @throws Exception
   */
  public void addActors() throws Exception {
    E3DSector sector = world.getSector("sector0"); // Grab our main sector.
    //		E3DSector sector1 = world.getSector("sector1");  //Grab our main sector.
    //		E3DSector sector2 = world.getSector("sector2");  //Grab our main sector.

    E3DViewport viewport = engine.getWindow().getViewport("viewport1"); // Grab the viewport

    cameraActor = new E3DCameraActor(engine, world, "camera");
    cameraActor.rotate(E3DConstants.PI, cameraActor.getOrientation().getUp());
    sector.addActor(cameraActor);

    viewport.setCameraActor(cameraActor);

    E3DLight light = new E3DLight(engine, "light1");
    light.setPosition(new E3DVector3F(-5.0, -5.0, -5.0));
    light.setBrightness(150);
    light.setColor(new E3DVector4F(1.0, 1.0, 1.0, 1.0));
    sector.addLight(light);

    sector.addParticleSystem(new FireParticleSystem(engine));

    /*        FireParticleSystem system2 = new FireParticleSystem(engine);
           system2.setPosition(new E3DVector3F(10, 0, 0));
           sector.addParticleSystem(system2);
    */
    //        BluePlasmaWallParticleSystem system3 = new BluePlasmaWallParticleSystem(engine);
    //        system3.setPosition(new E3DVector3F(0, 0, -10));
    //        sector.addParticleSystem(system3);

  }
  /**
   * Check if a Portal is in view of the frustum.
   *
   * @return Returns true if the portal is visible by this frustum
   */
  public boolean isPortalInFrustum(E3DPortal portal) {
    E3DVector3F[] proj = new E3DVector3F[4];

    E3DVector3F portalA = portal.getA();
    E3DVector3F portalB = portal.getB();
    E3DVector3F portalC = portal.getC();
    E3DVector3F portalD = portal.getD();

    // Project all the corners of the portal that we are trying to see is in this frustum

    proj[0] = viewport.projectPoint(portalA);
    proj[0].setZ(0.0);

    proj[1] = viewport.projectPoint(portalB);
    proj[1].setZ(0.0);

    proj[2] = viewport.projectPoint(portalC);
    proj[2].setZ(0.0);

    proj[3] = viewport.projectPoint(portalD);
    proj[3].setZ(0.0);

    /** 1. Check if a portal corner point is in the frustum */
    for (int i = 0; i < 4; i++) {
      if (projectedPointInFrustum(proj[i])) return true;
    }

    /** 2. Check if a frustum corner point is in the portal */
    E3DTriangle portalTriA = new E3DTriangle(getEngine(), proj[0], proj[1], proj[3]);
    E3DTriangle portalTriB = new E3DTriangle(getEngine(), proj[1], proj[2], proj[3]);

    if (portalTriA.isPointInTriangle(a)
        || portalTriB.isPointInTriangle(a)
        || portalTriA.isPointInTriangle(b)
        || portalTriB.isPointInTriangle(b)
        || portalTriA.isPointInTriangle(c)
        || portalTriB.isPointInTriangle(c)
        || portalTriA.isPointInTriangle(d)
        || portalTriB.isPointInTriangle(d)) return true;

    /** 3. Check if any of the line segments intersect */
    if (get2DLineIntersectionPt(a, b, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(a, b, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(a, b, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(a, b, proj[3], proj[0]) != null
        || get2DLineIntersectionPt(b, c, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(b, c, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(b, c, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(b, c, proj[3], proj[0]) != null
        || get2DLineIntersectionPt(c, d, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(c, d, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(c, d, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(c, d, proj[3], proj[0]) != null
        || get2DLineIntersectionPt(d, a, proj[0], proj[1]) != null
        || get2DLineIntersectionPt(d, a, proj[1], proj[2]) != null
        || get2DLineIntersectionPt(d, a, proj[2], proj[3]) != null
        || get2DLineIntersectionPt(d, a, proj[3], proj[0]) != null) return true;

    return false;
  }
  /**
   * This initializes the engine and variables required by the engine.
   *
   * @throws E3DInvalidDisplayModeException
   * @throws LWJGLException
   * @throws Exception
   */
  private void initGame() throws E3DInvalidDisplayModeException, LWJGLException, Exception {
    // Initialize the engine
    engine.initEngine(width, height, 32, false, "Espresso3D TestBed");
    engine.getLogger().setDebug(true);
    // engine.setBackfaceCullingEnabled(true);

    // Setup the world
    world = new E3DWorld(engine, "worldOne"); // create the world and give it an ID
    world.loadTextureSet("espresso3d\\testbed\\media\\textures\\textureseta.txt");

    // Add the world to the engine itself.  The world MUST be added to the engine
    // before preloading of particles occur, otherwise textures will not be found for
    // the particles.
    engine.addWorld(world);

    // Preload all the potential actors that can be loaded from the mapfile
    // Preloading is a necessary step before the world is loaded.  Without preloading,
    // the world will have no idea how to load an actor that is in the mapfile
    world.addPreloadedParticleSystem("FIRE", new FireParticleSystem(engine));

    // Load the mapfile.  If there are actors in the mapfile, this must come after preloading the
    // actors
    world.loadWorld("espresso3d//testbed//media//maps//pongroom.e3m");

    // Setup the engine's viewport.  There can be many of these in an engine.
    //  A viewport is required to see anything.  The viewport specifies its dimensions and
    //  which world gets rendered in it.
    viewport =
        new E3DViewport(
            engine,
            0,
            0,
            width,
            height,
            "viewport1"); // create the viewport starting at 0,0 and extending to width, height (the
    // entire window)
    engine.getWindow().addViewport(viewport); // add the viewport to the engine.
    viewport.setWorld(world); // set the world we want the viewport to render in it

    // Bind all of our input handlers.  I do this in another class InputEvents
    inputEvents = new InputEvents(engine, world, this);
    inputEvents.bindInputEvents();
  }