Beispiel #1
0
        std::string GetFilenameWithoutExtension(const filesystem::path& filePath)
        {
            auto extension = filePath.extension();
            auto filename = filePath.filename();

            return !extension.empty() ? filename.substr(0, filename.length() - extension.length() - 1) : filename;
        }
Beispiel #2
0
    bool Parser::ParseWorkspace(const filesystem::path& filePath)
    {
        if (filePath.str().empty())
        {
            std::cout << "invalid workspace filename" << std::endl;
            return false;
        }

        WorkingDirectory::SetCurrent(filePath.make_absolute().parent_path().str());
        std::cout << "{ cwd : " << WorkingDirectory::GetCurrent() << " }" << std::endl;

        internal::EnsureDirectoryExists(outputDirectory_);

        auto workspace = JsonImporter::ImportWorkspace(pimpl_->GetFileManager(), filePath.filename());
        return ParseWorkspace(workspace.get());
    }
    //! The function stores the specified file in the storage
    void file_collector::store_file(filesystem::path const& src_path)
    {
        // NOTE FOR THE FOLLOWING CODE:
        // Avoid using Boost.Filesystem functions that would call path::codecvt(). store_file() can be called
        // at process termination, and the global codecvt facet can already be destroyed at this point.
        // https://svn.boost.org/trac/boost/ticket/8642

        // Let's construct the new file name
        file_info info;
        info.m_TimeStamp = filesystem::last_write_time(src_path);
        info.m_Size = filesystem::file_size(src_path);

        filesystem::path file_name_path = src_path.filename();
        path_string_type file_name = file_name_path.native();
        info.m_Path = m_StorageDir / file_name_path;

        // Check if the file is already in the target directory
        filesystem::path src_dir = src_path.has_parent_path() ?
                            filesystem::system_complete(src_path.parent_path()) :
                            m_BasePath;
        const bool is_in_target_dir = filesystem::equivalent(src_dir, m_StorageDir);
        if (!is_in_target_dir)
        {
            if (filesystem::exists(info.m_Path))
            {
                // If the file already exists, try to mangle the file name
                // to ensure there's no conflict. I'll need to make this customizable some day.
                file_counter_formatter formatter(file_name.size(), 5);
                unsigned int n = 0;
                do
                {
                    path_string_type alt_file_name = formatter(file_name, n++);
                    info.m_Path = m_StorageDir / filesystem::path(alt_file_name);
                }
                while (filesystem::exists(info.m_Path) && n < (std::numeric_limits< unsigned int >::max)());
            }

            // The directory should have been created in constructor, but just in case it got deleted since then...
            filesystem::create_directories(m_StorageDir);
        }

        BOOST_LOG_EXPR_IF_MT(lock_guard< mutex > lock(m_Mutex);)
 //! Acquires file name string from the path
 static path_string_type filename_string(filesystem::path const& p)
 {
     return p.filename().string< path_string_type >();
 }
Beispiel #5
0
void 
Scene::load(const filesystem::path &file)
{
  size_t i;
  std::string message;

  if(!filesystem::exists(file))
    throw std::runtime_error(std::string("File does not exists:") + file.string());

  this->collada = new DAE;

  message = "Start loading COLLADA DOM from ";
  message += file.string();
  this->scene_graph.printStatusMessage(message); 
  this->dae_file_name = file;

  // load with full path 
  domCOLLADA *dom = this->collada->open(file.string());
  if(!dom)
    {
      delete this->collada;	
      throw std::runtime_error(std::string("Error loading the COLLADA file ") 
			  + file.string() 
			  + ". Make sure it is COLLADA 1.4 or greater");
    }

  this->scene_graph.printStatusMessage("Begin conditioning");

  //if(kmzcleanup(this->collada, true))
  //  std::cout << "  kmzcleanup complete\n";
  int res = 0;

  this->scene_graph.printStatusMessage("  triangulating");
  res = triangulate(this->collada);
	if(res)
  {
    std::ostringstream os;
    os << "  triangulation returns error " << res << std::ends;
    this->scene_graph.printStatusMessage(os.str());
  }
  else
    this->scene_graph.printStatusMessage(std::string("  triangulation complete"));
/*
  this->scene_graph.printStatusMessage(std::string("  deindexing"));
  res = deindex(this->collada);
	if(res)
  {
    std::ostringstream os;
    os << "  deindexer returns error " << res << std::ends;
    this->scene_graph.printStatusMessage(os.str());
  }
  else
    this->scene_graph.printStatusMessage(std::string("  deindexing complete"));
*/
  this->scene_graph.printStatusMessage(std::string("Finish conditioning."));

  // Need to get the asset tag which will determine what vector x y or z is up.  Typically y or z. 
  domAssetRef asset = dom->getAsset();
  this->scene_graph.printStatusMessage(std::string("File information:"));
  const domAsset::domContributor_Array &contributors = asset->getContributor_array();
  for(i = 0; i < contributors.getCount(); ++i)
  {
    domAsset::domContributorRef c = contributors.get(i);
    this->scene_graph.printStatusMessage(std::string("  author:") + c->getAuthor()->getCharData());
    this->scene_graph.printStatusMessage(std::string("  authoring tool:") + c->getAuthoring_tool()->getCharData());
  }
  if(asset->getCreated())
    this->scene_graph.printStatusMessage(std::string("  created: ") + asset->getCreated()->getCharData());
  if(asset->getModified())
    this->scene_graph.printStatusMessage(std::string("  modified: ") + asset->getModified()->getCharData());
  if(asset->getUnit())
  {
    std::ostringstream os;
    os << "  units: " << asset->getUnit()->getMeter() << " meter (" << asset->getUnit()->getAttribute("name") << ")";
    os << std::ends;
    this->scene_graph.printStatusMessage(os.str());
  }
  if(asset->getUp_axis())
    {
      domAsset::domUp_axis *up = dom->getAsset()->getUp_axis();
      if(up)
        this->up_axis = up->getValue();
      switch(this->up_axis)
        {
        case UPAXISTYPE_X_UP:
          this->scene_graph.printStatusMessage(std::string("  X axis is UP axis.")); 
          break; 

        case UPAXISTYPE_Y_UP:
          this->scene_graph.printStatusMessage(std::string("  Y axis is UP axis.")); 
          break;

        case UPAXISTYPE_Z_UP:
          this->scene_graph.printStatusMessage(std::string("  Z axis is UP axis.")); 
          break; 

        default:
          break; 
        }
  	}

  this->scene_graph.printStatusMessage("Building libraries");
 	
  // Load the image for the default texture.

  const Image::ImageID image_key = {"default", ""};
  bool inserted;
  Image::ImageList::iterator img_iter;
  tie(img_iter, inserted) = this->scene_graph.all_images.insert(std::make_pair(image_key, Image()));

  Image &img = img_iter->second;
  img.image = IMG_Load("default.tga");
  if(!img.image)
  {
    scene_graph.all_images.erase(image_key);
    this->scene_graph.printStatusMessage("Can not load default.tga for the default texture.");
  }

  this->scene_graph.printStatusMessage("  Load image libraries");
  const domLibrary_images_Array &ia = dom->getLibrary_images_array();
	for(i = 0; i < ia.getCount(); ++i)
		this->readImageLibrary(ia[i]);

  this->scene_graph.printStatusMessage("  Load effect libraries");
  const domLibrary_effects_Array &ea = dom->getLibrary_effects_array();
	for(i = 0; i < ea.getCount(); i++)
		this->readEffectLibrary(ea[i]);

  this->scene_graph.printStatusMessage("  Load material libraries");
  const domLibrary_materials_Array &ma = dom->getLibrary_materials_array();
	for(i = 0; i < ma.getCount(); i++)
		this->readMaterialLibrary(ma[i]);

  this->scene_graph.printStatusMessage("  Load animation libraries");
  const domLibrary_animations_Array &aa = dom->getLibrary_animations_array();
	for(i = 0; i < aa.getCount(); i++)
		this->readAnimationLibrary(aa[i]);

	// Find the scene we want
	domCOLLADA::domSceneRef domScene = dom->getScene();
	daeElement* defaultScene = NULL;
	if (domScene)
		if (domScene->getInstance_visual_scene())
			if (domScene->getInstance_visual_scene())
				defaultScene = domScene->getInstance_visual_scene()->getUrl().getElement();
	if(defaultScene)
		this->readScene((domVisual_scene*)defaultScene);

	// If no lights were loaded, we need to make one so the scene won't be totally black
	if(this->scene_graph.all_lights.empty())
	{
		// new Light  
		this->scene_graph.printStatusMessage("Scene: no lights were loaded. Creating a default light");
    const Light::LightID light_key = 
      {"no_light_in_scene_default_light", dom->getDocumentURI()->getURI()};
    bool inserted;
    Light::LightList::iterator light;
    tie(light, inserted) = scene_graph.all_lights.insert(std::make_pair(light_key, Light()));
    Light &default_light = light->second;
		default_light.type = Light::DIRECTIONAL;
		default_light.color = Color4f(1, 1, 1, 1);

		// new Node
		this->scene_graph.printStatusMessage("Scene: no instance_light found creating a node with an instance");
    this->scene_graph.insertNode(this->scene_graph.root,
                                 "no_light_in_scene_default_node",
                                 "no_light_in_scene_default_node",
                                 "NONE");
    // Read node transformations
    Node &current_node = *this->scene_graph.all_nodes.find("no_light_in_scene_default_node");

    current_node.transformations.push_back(Transformation());
    Transformation &transform = 
      current_node.transformations.at(current_node.transformations.size() - 1);
		transform.type = Transformation::Translate; 
		const Vector3 trans(-40.0, 40.0, 0.0);
    transform.transform = Transform3::translation(trans);

		// new InstanceLight
    InstanceLight instance_light;
    instance_light.abstract_light_ref = light->first;
    current_node.instance_lights.push_back(instance_light);
    this->scene_graph.light_nodes.push_back("no_light_in_scene_default_node"); 
  }

  if(!this->scene_graph.all_cameras.empty())
  {
    // Search for the first camera node
    Node::NodeMap &all_nodes = this->scene_graph.all_nodes;
    for(int n = 0; n < all_nodes.size(); ++n)
    {
      Node *node = all_nodes.getAtIndex(n);
      if(node->instance_cameras.size() > 0)
      {
        this->scene_graph.active_camera_info = std::make_pair(node, &(node->instance_cameras[0]));
        break;
      }
    }
  }
  else
	{
		this->scene_graph.printStatusMessage( "Scene: create a default camera and it is the first camera to use");
		// new Camera
    const Camera::CameraID camera_key = 
      {"no_camera_in_scene_default_camera", dom->getDocumentURI()->getURI()};

	  // Make the camera
    bool inserted;
    Camera::CameraList::iterator camera;
    tie(camera, inserted) = this->scene_graph.all_cameras.insert(std::make_pair(camera_key, Camera()));
    Camera &default_camera = camera->second;
    default_camera.Xfov = 45.0f;
    default_camera.Yfov = 45.0f;

		this->scene_graph.printStatusMessage( "Scene: creating a node with an instance of default camera");
		// new Node
    this->scene_graph.insertNode(this->scene_graph.root,
                                 "no_camera_in_scene_default_node",
                                 "no_camera_in_scene_default_node",
                                 "NONE");
    // Read node transformations
    Node &current_node = *this->scene_graph.all_nodes.find("no_camera_in_scene_default_node");

    // Calculate approximate bounding box for the model
    Vector3 max(0,0,0);
    Vector3 min(0,0,0);
    for(Geometry::GeometryList::const_iterator g = this->scene_graph.all_geometries.begin();
      g != this->scene_graph.all_geometries.end(); ++g)
    {
      // Points are stored as x/y/z tripples within this array
      for(Geometry::PointList::const_iterator p = g->second.points.begin();
        p != g->second.points.end(); ++p)
      {
        // X
        if(*p > max.getX())
          max.setX(*p);
        else if(*p < min.getX())
          min.setX(*p);
        // Y
        ++p;
        if(*p > max.getY())
          max.setY(*p);
        else if(*p < min.getY())
          min.setY(*p);
        // Z
        ++p;
        if(*p > max.getZ())
          max.setZ(*p);
        else if(*p < min.getZ())
          min.setZ(*p);
      }
    }

    default_camera.ZNear = 1.0f;
		default_camera.ZFar = 1000.0f;

    current_node.transformations.push_back(Transformation());
    Transformation &transform = 
      current_node.transformations.at(current_node.transformations.size() - 1);
    transform.type = Transformation::LookAt;
    const Point3 eyePos(max.getX() * 0.5f, max.getY() * 0.5f, max.getZ() * 0.5f);
    const Point3 lookAtPos(min.getX(), min.getY(), min.getZ());
    Vector3 upVec;
    upVec.setY(0);
		if(this->up_axis == UPAXISTYPE_Z_UP)
    {
      upVec.setX(0);
      upVec.setZ(1.0f);
    }
		else if(this->up_axis == UPAXISTYPE_X_UP)
    {
      upVec.setX(1.0f);
      upVec.setZ(0);
    }
    // Store transformation
    transform.matrix = inverse(Matrix4::lookAt(eyePos, lookAtPos, upVec));
    current_node.local_matrix *= transform.matrix;

    // new InstanceCamera
    InstanceCamera instance_camera;
    instance_camera.abstract_camera_ref = camera->first;
    current_node.instance_cameras.push_back(instance_camera);
    this->scene_graph.active_camera_info = std::make_pair(&current_node,
      &(current_node.instance_cameras.at(current_node.instance_cameras.size() - 1)));
	}

  this->scene_graph.printStatusMessage(std::string("COLLADA_DOM runtime database initialized from ") + file.filename().string());
}