예제 #1
0
World::World(WindowFramework* windowFrameworkPtr)
   : m_windowFrameworkPtr(windowFrameworkPtr)
   {
   // preconditions
   if(m_windowFrameworkPtr == NULL)
      {
      nout << "ERROR: World::World(WindowFramework* windowFrameworkPtr) parameter windowFrameworkPtr cannot be NULL." << endl;
      return;
      }

   m_keyMap.resize(K_keys);
   m_keyMap[K_left     ] = false;
   m_keyMap[K_right    ] = false;
   m_keyMap[K_forward  ] = false;
   m_keyMap[K_cam_left ] = false;
   m_keyMap[K_cam_right] = false;
   m_windowFrameworkPtr->set_background_type(WindowFramework::BT_black);

   // Post the instructions

   m_titleNp = add_title("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)");
   m_inst1Np = add_instructions(0.95, "[ESC]: Quit");
   m_inst2Np = add_instructions(0.90, "[Left Arrow]: Rotate Ralph Left");
   m_inst3Np = add_instructions(0.85, "[Right Arrow]: Rotate Ralph Right");
   m_inst4Np = add_instructions(0.80, "[Up Arrow]: Run Ralph Forward");
   m_inst6Np = add_instructions(0.70, "[A]: Rotate Camera Left");
   m_inst7Np = add_instructions(0.65, "[S]: Rotate Camera Right");

   // Set up the environment
   //
   // This environment model contains collision meshes.  If you look
   // in the egg file, you will see the following:
   //
   //    <Collide> { Polyset keep descend }
   //
   // This tag causes the following mesh to be converted to a collision
   // mesh -- a mesh which is optimized for collision, not rendering.
   // It also keeps the original mesh, so there are now two copies ---
   // one optimized for rendering, one for collisions.

   NodePath modelsNp = m_windowFrameworkPtr->get_panda_framework()->get_models();
   m_environNp = m_windowFrameworkPtr->load_model(modelsNp, "../models/world");
   NodePath renderNp = m_windowFrameworkPtr->get_render();
   m_environNp.reparent_to(renderNp);
   m_environNp.set_pos(0,0,0);

   // Create the main character, Ralph
   LPoint3f ralphStartPos = m_environNp.find("**/start_point").get_pos();
   CActor::AnimMap ralphAnims;
   ralphAnims["../models/ralph-run"].push_back("run");
   ralphAnims["../models/ralph-walk"].push_back("walk");
   m_ralph.load_actor(m_windowFrameworkPtr,
                      "../models/ralph",
                      &ralphAnims,
                      PartGroup::HMF_ok_wrong_root_name|
                      PartGroup::HMF_ok_anim_extra|
                      PartGroup::HMF_ok_part_extra);
   m_ralph.reparent_to(renderNp);
   m_ralph.set_scale(0.2);
   m_ralph.set_pos(ralphStartPos);

   // Create a floater object.  We use the "floater" as a temporary
   // variable in a variety of calculations.

   m_floaterNp = NodePath("floater");
   m_floaterNp.reparent_to(renderNp);

   // Accept the control keys for movement and rotation
   m_windowFrameworkPtr->enable_keyboard();
   m_windowFrameworkPtr->get_panda_framework()->define_key("escape"        , "sysExit"    , sys_exit                        , NULL);
   m_windowFrameworkPtr->get_panda_framework()->define_key("arrow_left"    , "left"       , call_set_key<K_left     , true >, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("arrow_right"   , "right"      , call_set_key<K_right    , true >, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("arrow_up"      , "forward"    , call_set_key<K_forward  , true >, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("a"             , "cam-left"   , call_set_key<K_cam_left , true >, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("s"             , "cam-right"  , call_set_key<K_cam_right, true >, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("arrow_left-up" , "leftUp"     , call_set_key<K_left     , false>, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("arrow_right-up", "rightUp"    , call_set_key<K_right    , false>, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("arrow_up-up"   , "forwardUp"  , call_set_key<K_forward  , false>, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("a-up"          , "cam-leftUp" , call_set_key<K_cam_left , false>, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("s-up"          , "cam-rightUp", call_set_key<K_cam_right, false>, this);

   PT(GenericAsyncTask) taskPtr = new GenericAsyncTask("moveTask", call_move, this);
   if(taskPtr != NULL)
      {
      AsyncTaskManager::get_global_ptr()->add(taskPtr);
      }

   // Game state variables
   m_isMoving = false;

   // Set up the camera

   // Note: no need to disable the mouse in C++
   NodePath cameraNp = m_windowFrameworkPtr->get_camera_group();
   cameraNp.set_pos(m_ralph.get_x(), m_ralph.get_y()+10, 2);

   // We will detect the height of the terrain by creating a collision
   // ray and casting it downward toward the terrain.  One ray will
   // start above ralph's head, and the other will start above the camera.
   // A ray may hit the terrain, or it may hit a rock or a tree.  If it
   // hits the terrain, we can detect the height.  If it hits anything
   // else, we rule that the move is illegal.

   NodePath ralphGroundColNp;
   m_ralphGroundRayPtr = new CollisionRay();
   if(m_ralphGroundRayPtr != NULL)
      {
      m_ralphGroundRayPtr->set_origin(0, 0, 1000);
      m_ralphGroundRayPtr->set_direction(0, 0, -1);
      m_ralphGroundColPtr = new CollisionNode("ralphRay");
      if(m_ralphGroundColPtr != NULL)
         {
         m_ralphGroundColPtr->add_solid(m_ralphGroundRayPtr);
         m_ralphGroundColPtr->set_from_collide_mask(BitMask32::bit(0));
         m_ralphGroundColPtr->set_into_collide_mask(BitMask32::all_off());
         ralphGroundColNp = m_ralph.attach_new_node(m_ralphGroundColPtr);
         m_ralphGroundHandlerPtr = new CollisionHandlerQueue();
         if(m_ralphGroundHandlerPtr != NULL)
            {
            m_collisionTraverser.add_collider(ralphGroundColNp, m_ralphGroundHandlerPtr);
            }
         }
      }

   NodePath camGroundColNp;
   m_camGroundRayPtr = new CollisionRay();
   if(m_camGroundRayPtr != NULL)
      {
      m_camGroundRayPtr->set_origin(0, 0, 1000);
      m_camGroundRayPtr->set_direction(0, 0, -1);
      m_camGroundColPtr = new CollisionNode("camRay");
      if(m_camGroundColPtr != NULL)
         {
         m_camGroundColPtr->add_solid(m_camGroundRayPtr);
         m_camGroundColPtr->set_from_collide_mask(BitMask32::bit(0));
         m_camGroundColPtr->set_into_collide_mask(BitMask32::all_off());
         camGroundColNp = cameraNp.attach_new_node(m_camGroundColPtr);
         m_camGroundHandlerPtr = new CollisionHandlerQueue();
         if(m_camGroundHandlerPtr != NULL)
            {
            m_collisionTraverser.add_collider(camGroundColNp, m_camGroundHandlerPtr);
            }
         }
      }

   // Uncomment this line to see the collision rays
   //ralphGroundColNp.show();
   //camGroundColNp.show();

   // Uncomment this line to show a visual representation of the
   // collisions occuring
   //m_collisionTraverser.show_collisions(renderNp);

   // Create some lighting
   PT(AmbientLight) ambientLightPtr = new AmbientLight("ambientLight");
   if(ambientLightPtr != NULL)
      {
      ambientLightPtr->set_color(Colorf(.3, .3, .3, 1));
      renderNp.set_light(renderNp.attach_new_node(ambientLightPtr));
      }
   PT(DirectionalLight) directionalLightPtr = new DirectionalLight("directionalLightPtr");
   if(directionalLightPtr != NULL)
      {
      directionalLightPtr->set_direction(LVecBase3f(-5, -5, -5));
      directionalLightPtr->set_color(Colorf(1, 1, 1, 1));
      directionalLightPtr->set_specular_color(Colorf(1, 1, 1, 1));
      renderNp.set_light(renderNp.attach_new_node(directionalLightPtr));
      }
   }
예제 #2
0
World::World(WindowFramework* windowFramework)
    : m_windowFramework(windowFramework),
      m_title(),
      m_inst1(),
      m_inst2(),
      m_inst3(),
      m_inst4(),
      m_altCam(),
      m_teapot(),
      m_teapotInterval(),
      m_bufferViewer(NULL)
      // m_tvMen
{
    // Note: set background color here
    m_windowFramework->get_graphics_output()->get_active_display_region(0)->
    set_clear_color(Colorf(0, 0, 0, 1));

    // Post the instructions.
    m_title = add_title("Panda3D: Tutorial - Using Render-to-Texture");
    m_inst1 = add_instructions(0.95,"ESC: Quit");
    m_inst2 = add_instructions(0.90,"Up/Down: Zoom in/out on the Teapot");
    m_inst3 = add_instructions(0.85,"Left/Right: Move teapot left/right");
    m_inst4 = add_instructions(0.80,"V: View the render-to-texture results");

    //we get a handle to the default window
    PT(GraphicsOutput) mainWindow = m_windowFramework->get_graphics_output();

    // we now get buffer thats going to hold the texture of our new scene
    PT(GraphicsOutput) altBuffer = mainWindow->make_texture_buffer(
                                       "hello", 256, 256);

    // now we have to setup a new scene graph to make this scene
    NodePath altRender("new render");

    // this takes care of setting up the camera properly
    m_altCam = m_windowFramework->make_camera();
    // Note: set the size and shape of the "film" within the lens equal to the
    //       buffer of our new scene
    DCAST(Camera, m_altCam.node())->get_lens()->set_film_size(
        altBuffer->get_x_size(), altBuffer->get_y_size());
    // Note: make a DisplayRegion for the camera
    PT(DisplayRegion) dr = altBuffer->make_display_region(0, 1, 0, 1);
    dr->set_sort(0);
    dr->set_camera(m_altCam);
    m_altCam.reparent_to(altRender);
    m_altCam.set_pos(0, -10, 0);

    // get the teapot and rotates it for a simple animation
    const NodePath& models =
        m_windowFramework->get_panda_framework()->get_models();
    m_teapot = m_windowFramework->load_model(models, "../models/teapot");
    m_teapot.reparent_to(altRender);
    m_teapot.set_pos(0, 0, -1);

    const bool bakeInStart = true;
    const bool fluid = false;
    m_teapotInterval = new CLerpNodePathInterval("teapotInterval", 1.5,
            CLerpInterval::BT_no_blend, bakeInStart, fluid, m_teapot, NodePath());
    m_teapotInterval->set_start_hpr(m_teapot.get_hpr());
    m_teapotInterval->set_end_hpr(LVecBase3f(m_teapot.get_h()+360,
                                  m_teapot.get_p()+360,
                                  m_teapot.get_r()+360));
    m_teapotInterval->loop();

    // put some lighting on the teapot
    PT(DirectionalLight) dlight = new DirectionalLight("dlight");
    PT(AmbientLight) alight = new AmbientLight("alight");
    NodePath dlnp = altRender.attach_new_node(dlight);
    NodePath alnp = altRender.attach_new_node(alight);
    dlight->set_color(Colorf(0.8, 0.8, 0.5, 1));
    alight->set_color(Colorf(0.2, 0.2, 0.2, 1));
    dlnp.set_hpr(0, -60, 0);
    altRender.set_light(dlnp);
    altRender.set_light(alnp);

    // Panda contains a built-in viewer that lets you view the results of
    // your render-to-texture operations.  This code configures the viewer.

    WORLD_DEFINE_KEY("v", "toggleBufferViewer", toggle_buffer_viewer);
    m_bufferViewer = new CBufferViewer(m_windowFramework);
    m_bufferViewer->set_position(CBufferViewer::CP_llcorner);
    m_bufferViewer->set_card_size(1.0, 0.0);

    // Create the tv-men. Each TV-man will display the
    // offscreen-texture on his TV screen.
    make_tv_man(-5, 30,  1, altBuffer->get_texture(), 0.9);
    make_tv_man( 5, 30,  1, altBuffer->get_texture(), 1.4);
    make_tv_man( 0, 23, -3, altBuffer->get_texture(), 2.0);
    make_tv_man(-5, 20, -6, altBuffer->get_texture(), 1.1);
    make_tv_man( 5, 18, -5, altBuffer->get_texture(), 1.7);

    WORLD_DEFINE_KEY("escape", "exit", quit);
    WORLD_DEFINE_KEY("arrow_up", "zoomIn", zoom_in);
    WORLD_DEFINE_KEY("arrow_down", "zoomOut", zoom_out);
    WORLD_DEFINE_KEY("arrow_left", "moveLeft", move_left);
    WORLD_DEFINE_KEY("arrow_right", "moveRight", move_right);

    WORLD_ADD_TASK("worldAsyncTask", async_task);
}