mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-13 13:20:07 +00:00
Merge pull request #4181 from erwincoumans/master
rename tiny_obj_loader.h namespace to bt_tinyobj to avoid conflicts
This commit is contained in:
commit
58cde7b598
@ -30,13 +30,13 @@
|
||||
#include "Bullet3Common/b3HashMap.h"
|
||||
#include "../Utils/b3BulletDefaultFileIO.h"
|
||||
|
||||
using tinyobj::index_t;
|
||||
using bt_tinyobj::index_t;
|
||||
|
||||
struct ShapeContainer
|
||||
{
|
||||
std::string m_matName;
|
||||
std::string m_shapeName;
|
||||
tinyobj::material_t material;
|
||||
bt_tinyobj::material_t material;
|
||||
std::vector<float> positions;
|
||||
std::vector<float> normals;
|
||||
std::vector<float> texcoords;
|
||||
@ -91,11 +91,11 @@ int main(int argc, char* argv[])
|
||||
char materialPrefixPath[MAX_PATH_LEN];
|
||||
b3FileUtils::extractPath(fileNameWithPath, materialPrefixPath, MAX_PATH_LEN);
|
||||
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
tinyobj::attrib_t attribute;
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
|
||||
b3BulletDefaultFileIO fileIO;
|
||||
std::string err = tinyobj::LoadObj(attribute, shapes, fileNameWithPath, materialPrefixPath,&fileIO);
|
||||
std::string err = bt_tinyobj::LoadObj(attribute, shapes, fileNameWithPath, materialPrefixPath, &fileIO);
|
||||
|
||||
char sdfFileName[MAX_PATH_LEN];
|
||||
sprintf(sdfFileName, "%s%s.sdf", materialPrefixPath, "newsdf");
|
||||
@ -110,8 +110,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
for (int s = 0; s < (int)shapes.size(); s++)
|
||||
{
|
||||
tinyobj::shape_t& shape = shapes[s];
|
||||
tinyobj::material_t mat = shape.material;
|
||||
bt_tinyobj::shape_t& shape = shapes[s];
|
||||
bt_tinyobj::material_t mat = shape.material;
|
||||
|
||||
b3HashString key = mat.name.length() ? mat.name.c_str() : "";
|
||||
if (!gMaterialNames.find(key))
|
||||
@ -212,7 +212,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
int faceCount = shapeCon->indices.size();
|
||||
int vertexCount = shapeCon->positions.size();
|
||||
tinyobj::material_t mat = shapeCon->material;
|
||||
bt_tinyobj::material_t mat = shapeCon->material;
|
||||
if (shapeCon->m_matName.length())
|
||||
{
|
||||
const char* objName = shapeCon->m_matName.c_str();
|
||||
@ -317,7 +317,7 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
for (int s = 0; s < (int)shapes.size(); s++)
|
||||
{
|
||||
tinyobj::shape_t& shape = shapes[s];
|
||||
bt_tinyobj::shape_t& shape = shapes[s];
|
||||
|
||||
if (shape.name.length())
|
||||
{
|
||||
@ -351,7 +351,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
int faceCount = shape.mesh.indices.size();
|
||||
int vertexCount = attribute.vertices.size();
|
||||
tinyobj::material_t mat = shape.material;
|
||||
bt_tinyobj::material_t mat = shape.material;
|
||||
if (shape.name.length())
|
||||
{
|
||||
const char* objName = shape.name.c_str();
|
||||
|
@ -2273,7 +2273,7 @@ int BulletMJCFImporter::getBodyUniqueId() const
|
||||
return m_data->m_activeBodyUniqueId;
|
||||
}
|
||||
|
||||
static btCollisionShape* MjcfCreateConvexHullFromShapes(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, const btVector3& geomScale, btScalar collisionMargin)
|
||||
static btCollisionShape* MjcfCreateConvexHullFromShapes(const bt_tinyobj::attrib_t& attribute, std::vector<bt_tinyobj::shape_t>& shapes, const btVector3& geomScale, btScalar collisionMargin)
|
||||
{
|
||||
btCompoundShape* compound = new btCompoundShape();
|
||||
compound->setMargin(collisionMargin);
|
||||
@ -2285,7 +2285,7 @@ static btCollisionShape* MjcfCreateConvexHullFromShapes(const tinyobj::attrib_t&
|
||||
{
|
||||
btConvexHullShape* convexHull = new btConvexHullShape();
|
||||
convexHull->setMargin(collisionMargin);
|
||||
tinyobj::shape_t& shape = shapes[s];
|
||||
bt_tinyobj::shape_t& shape = shapes[s];
|
||||
|
||||
int faceCount = shape.mesh.indices.size();
|
||||
|
||||
@ -2399,9 +2399,9 @@ class btCompoundShape* BulletMJCFImporter::convertLinkCollisionShapes(int linkIn
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
tinyobj::attrib_t attribute;
|
||||
std::string err = tinyobj::LoadObj(attribute, shapes, col->m_geometry.m_meshFileName.c_str(), "", m_data->m_fileIO);
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
std::string err = bt_tinyobj::LoadObj(attribute, shapes, col->m_geometry.m_meshFileName.c_str(), "", m_data->m_fileIO);
|
||||
//create a convex hull for each shape, and store it in a btCompoundShape
|
||||
|
||||
childShape = MjcfCreateConvexHullFromShapes(attribute, shapes, col->m_geometry.m_meshScale, m_data->m_globalDefaults.m_defaultCollisionMargin);
|
||||
|
@ -64,8 +64,8 @@ bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string&
|
||||
b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024);
|
||||
btVector3 shift(0, 0, 0);
|
||||
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
tinyobj::attrib_t attribute;
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
{
|
||||
B3_PROFILE("tinyobj::LoadObj");
|
||||
std::string err = LoadFromCachedOrFromObj(attribute, shapes, relativeFileName, pathPrefix, fileIO);
|
||||
@ -79,7 +79,7 @@ bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string&
|
||||
//try to load some texture
|
||||
for (int i = 0; meshData.m_textureImage1 == 0 && i < shapes.size(); i++)
|
||||
{
|
||||
const tinyobj::shape_t& shape = shapes[i];
|
||||
const bt_tinyobj::shape_t& shape = shapes[i];
|
||||
meshData.m_rgbaColor[0] = shape.material.diffuse[0];
|
||||
meshData.m_rgbaColor[1] = shape.material.diffuse[1];
|
||||
meshData.m_rgbaColor[2] = shape.material.diffuse[2];
|
||||
|
@ -11,8 +11,8 @@
|
||||
struct CachedObjResult
|
||||
{
|
||||
std::string m_msg;
|
||||
std::vector<tinyobj::shape_t> m_shapes;
|
||||
tinyobj::attrib_t m_attribute;
|
||||
std::vector<bt_tinyobj::shape_t> m_shapes;
|
||||
bt_tinyobj::attrib_t m_attribute;
|
||||
};
|
||||
|
||||
static b3HashMap<b3HashString, CachedObjResult> gCachedObjResults;
|
||||
@ -32,8 +32,8 @@ void b3EnableFileCaching(int enable)
|
||||
}
|
||||
|
||||
std::string LoadFromCachedOrFromObj(
|
||||
tinyobj::attrib_t& attribute,
|
||||
std::vector<tinyobj::shape_t>& shapes, // [output]
|
||||
bt_tinyobj::attrib_t& attribute,
|
||||
std::vector<bt_tinyobj::shape_t>& shapes, // [output]
|
||||
const char* filename,
|
||||
const char* mtl_basepath,
|
||||
struct CommonFileIOInterface* fileIO)
|
||||
@ -47,7 +47,7 @@ std::string LoadFromCachedOrFromObj(
|
||||
return result.m_msg;
|
||||
}
|
||||
|
||||
std::string err = tinyobj::LoadObj(attribute, shapes, filename, mtl_basepath, fileIO);
|
||||
std::string err = bt_tinyobj::LoadObj(attribute, shapes, filename, mtl_basepath, fileIO);
|
||||
CachedObjResult result;
|
||||
result.m_msg = err;
|
||||
result.m_shapes = shapes;
|
||||
@ -62,10 +62,10 @@ std::string LoadFromCachedOrFromObj(
|
||||
GLInstanceGraphicsShape* LoadMeshFromObj(const char* relativeFileName, const char* materialPrefixPath, struct CommonFileIOInterface* fileIO)
|
||||
{
|
||||
B3_PROFILE("LoadMeshFromObj");
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
tinyobj::attrib_t attribute;
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
{
|
||||
B3_PROFILE("tinyobj::LoadObj2");
|
||||
B3_PROFILE("bt_tinyobj::LoadObj2");
|
||||
std::string err = LoadFromCachedOrFromObj(attribute, shapes, relativeFileName, materialPrefixPath, fileIO);
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,8 @@ int b3IsFileCachingEnabled();
|
||||
void b3EnableFileCaching(int enable);
|
||||
|
||||
std::string LoadFromCachedOrFromObj(
|
||||
tinyobj::attrib_t& attribute,
|
||||
std::vector<tinyobj::shape_t>& shapes, // [output]
|
||||
bt_tinyobj::attrib_t& attribute,
|
||||
std::vector<bt_tinyobj::shape_t>& shapes, // [output]
|
||||
const char* filename,
|
||||
const char* mtl_basepath,
|
||||
struct CommonFileIOInterface* fileIO);
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "../../OpenGLWindow/GLInstancingRenderer.h"
|
||||
#include "../../OpenGLWindow/GLInstanceGraphicsShape.h"
|
||||
|
||||
GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, bool flatShading)
|
||||
GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const bt_tinyobj::attrib_t& attribute, std::vector<bt_tinyobj::shape_t>& shapes, bool flatShading)
|
||||
{
|
||||
b3AlignedObjectArray<GLInstanceVertex>* vertices = new b3AlignedObjectArray<GLInstanceVertex>;
|
||||
{
|
||||
@ -19,7 +19,7 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::a
|
||||
|
||||
for (int s = 0; s < (int)shapes.size(); s++)
|
||||
{
|
||||
tinyobj::shape_t& shape = shapes[s];
|
||||
bt_tinyobj::shape_t& shape = shapes[s];
|
||||
int faceCount = shape.mesh.indices.size();
|
||||
|
||||
for (int f = 0; f < faceCount; f += 3)
|
||||
@ -36,7 +36,7 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::a
|
||||
}
|
||||
|
||||
GLInstanceVertex vtx0;
|
||||
tinyobj::index_t v_0 = shape.mesh.indices[f];
|
||||
bt_tinyobj::index_t v_0 = shape.mesh.indices[f];
|
||||
vtx0.xyzw[0] = attribute.vertices[3 * v_0.vertex_index];
|
||||
vtx0.xyzw[1] = attribute.vertices[3 * v_0.vertex_index + 1];
|
||||
vtx0.xyzw[2] = attribute.vertices[3 * v_0.vertex_index + 2];
|
||||
@ -65,7 +65,7 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::a
|
||||
}
|
||||
|
||||
GLInstanceVertex vtx1;
|
||||
tinyobj::index_t v_1 = shape.mesh.indices[f + 1];
|
||||
bt_tinyobj::index_t v_1 = shape.mesh.indices[f + 1];
|
||||
vtx1.xyzw[0] = attribute.vertices[3 * v_1.vertex_index];
|
||||
vtx1.xyzw[1] = attribute.vertices[3 * v_1.vertex_index + 1];
|
||||
vtx1.xyzw[2] = attribute.vertices[3 * v_1.vertex_index + 2];
|
||||
@ -94,7 +94,7 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::a
|
||||
}
|
||||
|
||||
GLInstanceVertex vtx2;
|
||||
tinyobj::index_t v_2 = shape.mesh.indices[f + 2];
|
||||
bt_tinyobj::index_t v_2 = shape.mesh.indices[f + 2];
|
||||
vtx2.xyzw[0] = attribute.vertices[3 * v_2.vertex_index];
|
||||
vtx2.xyzw[1] = attribute.vertices[3 * v_2.vertex_index + 1];
|
||||
vtx2.xyzw[2] = attribute.vertices[3 * v_2.vertex_index + 2];
|
||||
|
@ -4,6 +4,6 @@
|
||||
#include "../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h"
|
||||
#include <vector>
|
||||
|
||||
struct GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, bool flatShading = false);
|
||||
struct GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const bt_tinyobj::attrib_t& attribute, std::vector<bt_tinyobj::shape_t>& shapes, bool flatShading = false);
|
||||
|
||||
#endif //WAVEFRONT2GRAPHICS_H
|
||||
|
@ -547,7 +547,7 @@ bool BulletURDFImporter::getRootTransformInWorld(btTransform& rootTransformInWor
|
||||
return true;
|
||||
}
|
||||
|
||||
static btCollisionShape* createConvexHullFromShapes(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, const btVector3& geomScale, int flags)
|
||||
static btCollisionShape* createConvexHullFromShapes(const bt_tinyobj::attrib_t& attribute, std::vector<bt_tinyobj::shape_t>& shapes, const btVector3& geomScale, int flags)
|
||||
{
|
||||
B3_PROFILE("createConvexHullFromShapes");
|
||||
btCompoundShape* compound = new btCompoundShape();
|
||||
@ -560,7 +560,7 @@ static btCollisionShape* createConvexHullFromShapes(const tinyobj::attrib_t& att
|
||||
{
|
||||
btConvexHullShape* convexHull = new btConvexHullShape();
|
||||
convexHull->setMargin(gUrdfDefaultCollisionMargin);
|
||||
tinyobj::shape_t& shape = shapes[s];
|
||||
bt_tinyobj::shape_t& shape = shapes[s];
|
||||
int faceCount = shape.mesh.indices.size();
|
||||
|
||||
for (int f = 0; f < faceCount; f += 3)
|
||||
@ -754,9 +754,9 @@ btCollisionShape* BulletURDFImporter::convertURDFToCollisionShape(const UrdfColl
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
tinyobj::attrib_t attribute;
|
||||
std::string err = tinyobj::LoadObj(attribute, shapes, collision->m_geometry.m_meshFileName.c_str(), "", m_data->m_fileIO);
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
std::string err = bt_tinyobj::LoadObj(attribute, shapes, collision->m_geometry.m_meshFileName.c_str(), "", m_data->m_fileIO);
|
||||
//create a convex hull for each shape, and store it in a btCompoundShape
|
||||
shape = createConvexHullFromShapes(attribute, shapes, collision->m_geometry.m_meshScale, m_data->m_flags);
|
||||
m_data->m_bulletCollisionShape2UrdfCollision.insert(shape, *collision);
|
||||
|
@ -5275,12 +5275,12 @@ bool PhysicsServerCommandProcessor::processCreateCollisionShapeCommand(const str
|
||||
{
|
||||
//create a convex hull for each shape, and store it in a btCompoundShape
|
||||
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
tinyobj::attrib_t attribute;
|
||||
std::string err = tinyobj::LoadObj(attribute, shapes, out_found_filename.c_str(), "", fileIO);
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
std::string err = bt_tinyobj::LoadObj(attribute, shapes, out_found_filename.c_str(), "", fileIO);
|
||||
|
||||
//shape = createConvexHullFromShapes(shapes, collision->m_geometry.m_meshScale);
|
||||
//static btCollisionShape* createConvexHullFromShapes(std::vector<tinyobj::shape_t>& shapes, const btVector3& geomScale)
|
||||
//static btCollisionShape* createConvexHullFromShapes(std::vector<bt_tinyobj::shape_t>& shapes, const btVector3& geomScale)
|
||||
B3_PROFILE("createConvexHullFromShapes");
|
||||
if (compound == 0)
|
||||
{
|
||||
@ -5292,7 +5292,7 @@ bool PhysicsServerCommandProcessor::processCreateCollisionShapeCommand(const str
|
||||
{
|
||||
btConvexHullShape* convexHull = worldImporter->createConvexHullShape();
|
||||
convexHull->setMargin(m_data->m_defaultCollisionMargin);
|
||||
tinyobj::shape_t& shape = shapes[s];
|
||||
bt_tinyobj::shape_t& shape = shapes[s];
|
||||
int faceCount = shape.mesh.indices.size();
|
||||
|
||||
for (int f = 0; f < faceCount; f += 3)
|
||||
@ -8975,12 +8975,12 @@ bool PhysicsServerCommandProcessor::processDeformable(const UrdfDeformable& defo
|
||||
}
|
||||
if (out_sim_type == UrdfGeometry::FILE_OBJ)
|
||||
{
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
tinyobj::attrib_t attribute;
|
||||
std::string err = tinyobj::LoadObj(attribute, shapes, out_found_sim_filename.c_str(), "", fileIO);
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
std::string err = bt_tinyobj::LoadObj(attribute, shapes, out_found_sim_filename.c_str(), "", fileIO);
|
||||
if (!shapes.empty())
|
||||
{
|
||||
const tinyobj::shape_t& shape = shapes[0];
|
||||
const bt_tinyobj::shape_t& shape = shapes[0];
|
||||
btAlignedObjectArray<btScalar> vertices;
|
||||
btAlignedObjectArray<int> indices;
|
||||
for (int i = 0; i < attribute.vertices.size(); i++)
|
||||
@ -9124,14 +9124,14 @@ bool PhysicsServerCommandProcessor::processDeformable(const UrdfDeformable& defo
|
||||
}
|
||||
else
|
||||
{
|
||||
tinyobj::attrib_t attribute;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
bt_tinyobj::attrib_t attribute;
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
|
||||
std::string err = tinyobj::LoadObj(attribute, shapes, out_found_filename.c_str(), pathPrefix, m_data->m_pluginManager.getFileIOInterface());
|
||||
std::string err = bt_tinyobj::LoadObj(attribute, shapes, out_found_filename.c_str(), pathPrefix, m_data->m_pluginManager.getFileIOInterface());
|
||||
|
||||
for (int s = 0; s < (int)shapes.size(); s++)
|
||||
{
|
||||
tinyobj::shape_t& shape = shapes[s];
|
||||
bt_tinyobj::shape_t& shape = shapes[s];
|
||||
int faceCount = shape.mesh.indices.size();
|
||||
int vertexCount = attribute.vertices.size() / 3;
|
||||
for (int v = 0; v < vertexCount; v++)
|
||||
@ -9146,9 +9146,9 @@ bool PhysicsServerCommandProcessor::processDeformable(const UrdfDeformable& defo
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tinyobj::index_t v_0 = shape.mesh.indices[f];
|
||||
tinyobj::index_t v_1 = shape.mesh.indices[f + 1];
|
||||
tinyobj::index_t v_2 = shape.mesh.indices[f + 2];
|
||||
bt_tinyobj::index_t v_0 = shape.mesh.indices[f];
|
||||
bt_tinyobj::index_t v_1 = shape.mesh.indices[f + 1];
|
||||
bt_tinyobj::index_t v_2 = shape.mesh.indices[f + 2];
|
||||
btSoftBody::RenderFace ff;
|
||||
ff.m_n[0] = &psb->m_renderNodes[v_0.vertex_index];
|
||||
ff.m_n[1] = &psb->m_renderNodes[v_1.vertex_index];
|
||||
|
@ -38,8 +38,8 @@ TestLoadObj(
|
||||
|
||||
std::cout << "Loading " << fullPath << std::endl;
|
||||
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::string err = tinyobj::LoadObj(shapes, fullPath, prefix[index]);
|
||||
std::vector<bt_tinyobj::shape_t> shapes;
|
||||
std::string err = bt_tinyobj::LoadObj(shapes, fullPath, prefix[index]);
|
||||
|
||||
if (!err.empty())
|
||||
{
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "tiny_obj_loader.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace tinyobj
|
||||
namespace bt_tinyobj
|
||||
{
|
||||
#ifdef USE_STREAM
|
||||
//See http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf
|
||||
@ -880,4 +880,4 @@ LoadObj(
|
||||
return err.str();
|
||||
}
|
||||
|
||||
}; // namespace tinyobj
|
||||
}; // namespace bt_tinyobj
|
||||
|
@ -3,8 +3,8 @@
|
||||
//
|
||||
// Licensed under 2-clause BSD liecense.
|
||||
//
|
||||
#ifndef _TINY_OBJ_LOADER_H
|
||||
#define _TINY_OBJ_LOADER_H
|
||||
#ifndef _BT_TINY_OBJ_LOADER_H
|
||||
#define _BT_TINY_OBJ_LOADER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
struct CommonFileIOInterface;
|
||||
|
||||
namespace tinyobj
|
||||
namespace bt_tinyobj
|
||||
{
|
||||
struct vertex_index_t
|
||||
{
|
||||
@ -94,6 +94,6 @@ LoadObj(
|
||||
CommonFileIOInterface* fileIO);
|
||||
#endif
|
||||
|
||||
}; // namespace tinyobj
|
||||
}; // namespace bt_tinyobj
|
||||
|
||||
#endif // _TINY_OBJ_LOADER_H
|
||||
#endif // _BT_TINY_OBJ_LOADER_H
|
||||
|
Loading…
Reference in New Issue
Block a user