Merge branch 'master' into ETC_Inc
commit
05ea039846
|
@ -890,7 +890,7 @@ SET( assimp_src
|
||||||
${PostProcessing_SRCS}
|
${PostProcessing_SRCS}
|
||||||
${MaterialSystem_SRCS}
|
${MaterialSystem_SRCS}
|
||||||
${STEPParser_SRCS}
|
${STEPParser_SRCS}
|
||||||
${Step_SRCS}
|
# ${Step_SRCS} check if we need a different approach
|
||||||
|
|
||||||
# Model Support
|
# Model Support
|
||||||
${ASSIMP_LOADER_SRCS}
|
${ASSIMP_LOADER_SRCS}
|
||||||
|
|
|
@ -870,10 +870,15 @@ namespace Assimp {
|
||||||
for (const Geometry* geo : geos) {
|
for (const Geometry* geo : geos) {
|
||||||
|
|
||||||
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
|
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
|
||||||
|
const LineGeometry* const line = dynamic_cast<const LineGeometry*>(geo);
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd);
|
const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd);
|
||||||
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
|
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
|
||||||
}
|
}
|
||||||
|
else if (line) {
|
||||||
|
const std::vector<unsigned int>& indices = ConvertLine(*line, model, node_global_transform, nd);
|
||||||
|
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name());
|
FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name());
|
||||||
}
|
}
|
||||||
|
@ -922,7 +927,52 @@ namespace Assimp {
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMesh* FBXConverter::SetupEmptyMesh(const MeshGeometry& mesh, aiNode& nd)
|
std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry& line, const Model& model,
|
||||||
|
const aiMatrix4x4& node_global_transform, aiNode& nd)
|
||||||
|
{
|
||||||
|
std::vector<unsigned int> temp;
|
||||||
|
|
||||||
|
const std::vector<aiVector3D>& vertices = line.GetVertices();
|
||||||
|
const std::vector<int>& indices = line.GetIndices();
|
||||||
|
if (vertices.empty() || indices.empty()) {
|
||||||
|
FBXImporter::LogWarn("ignoring empty line: " + line.Name());
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMesh* const out_mesh = SetupEmptyMesh(line, nd);
|
||||||
|
out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||||
|
|
||||||
|
// copy vertices
|
||||||
|
out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
|
||||||
|
out_mesh->mVertices = new aiVector3D[out_mesh->mNumVertices];
|
||||||
|
std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices);
|
||||||
|
|
||||||
|
//Number of line segments (faces) is "Number of Points - Number of Endpoints"
|
||||||
|
//N.B.: Endpoints in FbxLine are denoted by negative indices.
|
||||||
|
//If such an Index is encountered, add 1 and multiply by -1 to get the real index.
|
||||||
|
unsigned int epcount = 0;
|
||||||
|
for (unsigned i = 0; i < indices.size(); i++)
|
||||||
|
{
|
||||||
|
if (indices[i] < 0) epcount++;
|
||||||
|
}
|
||||||
|
unsigned int pcount = indices.size();
|
||||||
|
unsigned int scount = out_mesh->mNumFaces = pcount - epcount;
|
||||||
|
|
||||||
|
aiFace* fac = out_mesh->mFaces = new aiFace[scount]();
|
||||||
|
for (unsigned int i = 0; i < pcount; ++i) {
|
||||||
|
if (indices[i] < 0) continue;
|
||||||
|
aiFace& f = *fac++;
|
||||||
|
f.mNumIndices = 2; //2 == aiPrimitiveType_LINE
|
||||||
|
f.mIndices = new unsigned int[2];
|
||||||
|
f.mIndices[0] = indices[i];
|
||||||
|
int segid = indices[(i + 1 == pcount ? 0 : i + 1)]; //If we have reached he last point, wrap around
|
||||||
|
f.mIndices[1] = (segid < 0 ? (segid + 1)*-1 : segid); //Convert EndPoint Index to normal Index
|
||||||
|
}
|
||||||
|
temp.push_back(static_cast<unsigned int>(meshes.size() - 1));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd)
|
||||||
{
|
{
|
||||||
aiMesh* const out_mesh = new aiMesh();
|
aiMesh* const out_mesh = new aiMesh();
|
||||||
meshes.push_back(out_mesh);
|
meshes.push_back(out_mesh);
|
||||||
|
@ -957,6 +1007,7 @@ namespace Assimp {
|
||||||
// copy vertices
|
// copy vertices
|
||||||
out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
|
out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
|
||||||
out_mesh->mVertices = new aiVector3D[vertices.size()];
|
out_mesh->mVertices = new aiVector3D[vertices.size()];
|
||||||
|
|
||||||
std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices);
|
std::copy(vertices.begin(), vertices.end(), out_mesh->mVertices);
|
||||||
|
|
||||||
// generate dummy faces
|
// generate dummy faces
|
||||||
|
@ -1524,6 +1575,7 @@ namespace Assimp {
|
||||||
|
|
||||||
// shading stuff and colors
|
// shading stuff and colors
|
||||||
SetShadingPropertiesCommon(out_mat, props);
|
SetShadingPropertiesCommon(out_mat, props);
|
||||||
|
SetShadingPropertiesRaw( out_mat, props, material.Textures(), mesh );
|
||||||
|
|
||||||
// texture assignments
|
// texture assignments
|
||||||
SetTextureProperties(out_mat, material.Textures(), mesh);
|
SetTextureProperties(out_mat, material.Textures(), mesh);
|
||||||
|
@ -2023,6 +2075,180 @@ namespace Assimp {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
out_mat->AddProperty(&DispFactor, 1, "$mat.displacementscaling", 0, 0);
|
out_mat->AddProperty(&DispFactor, 1, "$mat.displacementscaling", 0, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTable& props, const TextureMap& textures, const MeshGeometry* const mesh)
|
||||||
|
{
|
||||||
|
// Add all the unparsed properties with a "$raw." prefix
|
||||||
|
|
||||||
|
const std::string prefix = "$raw.";
|
||||||
|
|
||||||
|
for (const DirectPropertyMap::value_type& prop : props.GetUnparsedProperties()) {
|
||||||
|
|
||||||
|
std::string name = prefix + prop.first;
|
||||||
|
|
||||||
|
if (const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >())
|
||||||
|
{
|
||||||
|
out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
||||||
|
}
|
||||||
|
else if (const TypedProperty<aiColor3D>* interpreted = prop.second->As<TypedProperty<aiColor3D> >())
|
||||||
|
{
|
||||||
|
out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
||||||
|
}
|
||||||
|
else if (const TypedProperty<aiColor4D>* interpreted = prop.second->As<TypedProperty<aiColor4D> >())
|
||||||
|
{
|
||||||
|
out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
||||||
|
}
|
||||||
|
else if (const TypedProperty<float>* interpreted = prop.second->As<TypedProperty<float> >())
|
||||||
|
{
|
||||||
|
out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
||||||
|
}
|
||||||
|
else if (const TypedProperty<int>* interpreted = prop.second->As<TypedProperty<int> >())
|
||||||
|
{
|
||||||
|
out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
||||||
|
}
|
||||||
|
else if (const TypedProperty<bool>* interpreted = prop.second->As<TypedProperty<bool> >())
|
||||||
|
{
|
||||||
|
int value = interpreted->Value() ? 1 : 0;
|
||||||
|
out_mat->AddProperty(&value, 1, name.c_str(), 0, 0);
|
||||||
|
}
|
||||||
|
else if (const TypedProperty<std::string>* interpreted = prop.second->As<TypedProperty<std::string> >())
|
||||||
|
{
|
||||||
|
const aiString value = aiString(interpreted->Value());
|
||||||
|
out_mat->AddProperty(&value, name.c_str(), 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the textures' properties
|
||||||
|
|
||||||
|
for (TextureMap::const_iterator it = textures.begin(); it != textures.end(); it++) {
|
||||||
|
|
||||||
|
std::string name = prefix + it->first;
|
||||||
|
|
||||||
|
const Texture* const tex = (*it).second;
|
||||||
|
if (tex != nullptr)
|
||||||
|
{
|
||||||
|
aiString path;
|
||||||
|
path.Set(tex->RelativeFilename());
|
||||||
|
|
||||||
|
const Video* media = tex->Media();
|
||||||
|
if (media != nullptr && media->ContentLength() > 0) {
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
VideoMap::const_iterator it = textures_converted.find(media);
|
||||||
|
if (it != textures_converted.end()) {
|
||||||
|
index = (*it).second;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
index = ConvertVideo(*media);
|
||||||
|
textures_converted[media] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
|
||||||
|
path.data[0] = '*';
|
||||||
|
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0);
|
||||||
|
|
||||||
|
aiUVTransform uvTrafo;
|
||||||
|
// XXX handle all kinds of UV transformations
|
||||||
|
uvTrafo.mScaling = tex->UVScaling();
|
||||||
|
uvTrafo.mTranslation = tex->UVTranslation();
|
||||||
|
out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0);
|
||||||
|
|
||||||
|
int uvIndex = 0;
|
||||||
|
|
||||||
|
bool uvFound = false;
|
||||||
|
const std::string& uvSet = PropertyGet<std::string>(tex->Props(), "UVSet", uvFound);
|
||||||
|
if (uvFound) {
|
||||||
|
// "default" is the name which usually appears in the FbxFileTexture template
|
||||||
|
if (uvSet != "default" && uvSet.length()) {
|
||||||
|
// this is a bit awkward - we need to find a mesh that uses this
|
||||||
|
// material and scan its UV channels for the given UV name because
|
||||||
|
// assimp references UV channels by index, not by name.
|
||||||
|
|
||||||
|
// XXX: the case that UV channels may appear in different orders
|
||||||
|
// in meshes is unhandled. A possible solution would be to sort
|
||||||
|
// the UV channels alphabetically, but this would have the side
|
||||||
|
// effect that the primary (first) UV channel would sometimes
|
||||||
|
// be moved, causing trouble when users read only the first
|
||||||
|
// UV channel and ignore UV channel assignments altogether.
|
||||||
|
|
||||||
|
std::vector<aiMaterial*>::iterator materialIt = std::find(materials.begin(), materials.end(), out_mat);
|
||||||
|
const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), materialIt));
|
||||||
|
|
||||||
|
uvIndex = -1;
|
||||||
|
if (!mesh)
|
||||||
|
{
|
||||||
|
for (const MeshMap::value_type& v : meshes_converted) {
|
||||||
|
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(v.first);
|
||||||
|
if (!mesh) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MatIndexArray& mats = mesh->GetMaterialIndices();
|
||||||
|
if (std::find(mats.begin(), mats.end(), matIndex) == mats.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||||
|
if (mesh->GetTextureCoords(i).empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const std::string& name = mesh->GetTextureCoordChannelName(i);
|
||||||
|
if (name == uvSet) {
|
||||||
|
index = static_cast<int>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index == -1) {
|
||||||
|
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uvIndex == -1) {
|
||||||
|
uvIndex = index;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FBXImporter::LogWarn("the UV channel named " + uvSet + " appears at different positions in meshes, results will be wrong");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = -1;
|
||||||
|
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||||
|
if (mesh->GetTextureCoords(i).empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const std::string& name = mesh->GetTextureCoordChannelName(i);
|
||||||
|
if (name == uvSet) {
|
||||||
|
index = static_cast<int>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index == -1) {
|
||||||
|
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uvIndex == -1) {
|
||||||
|
uvIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uvIndex == -1) {
|
||||||
|
FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
|
||||||
|
uvIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out_mat->AddProperty(&uvIndex, 1, (name + "|uvwsrc").c_str(), aiTextureType_UNKNOWN, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,11 @@ private:
|
||||||
const aiMatrix4x4& node_global_transform, aiNode& nd);
|
const aiMatrix4x4& node_global_transform, aiNode& nd);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiMesh* SetupEmptyMesh(const MeshGeometry& mesh, aiNode& nd);
|
std::vector<unsigned int> ConvertLine(const LineGeometry& line, const Model& model,
|
||||||
|
const aiMatrix4x4& node_global_transform, aiNode& nd);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode& nd);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
|
unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
|
||||||
|
@ -264,6 +268,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props);
|
void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props);
|
||||||
|
void SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTable& props, const TextureMap& textures, const MeshGeometry* const mesh);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// get the number of fps for a FrameRate enumerated value
|
// get the number of fps for a FrameRate enumerated value
|
||||||
|
@ -425,6 +430,7 @@ private:
|
||||||
std::vector<aiCamera*> cameras;
|
std::vector<aiCamera*> cameras;
|
||||||
std::vector<aiTexture*> textures;
|
std::vector<aiTexture*> textures;
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<const Material*, unsigned int> MaterialMap;
|
typedef std::map<const Material*, unsigned int> MaterialMap;
|
||||||
MaterialMap materials_converted;
|
MaterialMap materials_converted;
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,9 @@ const Object* LazyObject::Get(bool dieOnError)
|
||||||
if (!strcmp(classtag.c_str(), "Shape")) {
|
if (!strcmp(classtag.c_str(), "Shape")) {
|
||||||
object.reset(new ShapeGeometry(id, element, name, doc));
|
object.reset(new ShapeGeometry(id, element, name, doc));
|
||||||
}
|
}
|
||||||
|
if (!strcmp(classtag.c_str(), "Line")) {
|
||||||
|
object.reset(new LineGeometry(id, element, name, doc));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!strncmp(obtype,"NodeAttribute",length)) {
|
else if (!strncmp(obtype,"NodeAttribute",length)) {
|
||||||
if (!strcmp(classtag.c_str(),"Camera")) {
|
if (!strcmp(classtag.c_str(),"Camera")) {
|
||||||
|
|
|
@ -66,6 +66,7 @@ class PropertyTable;
|
||||||
class Document;
|
class Document;
|
||||||
class Material;
|
class Material;
|
||||||
class ShapeGeometry;
|
class ShapeGeometry;
|
||||||
|
class LineGeometry;
|
||||||
class Geometry;
|
class Geometry;
|
||||||
|
|
||||||
class Video;
|
class Video;
|
||||||
|
|
|
@ -679,6 +679,32 @@ const std::vector<aiVector3D>& ShapeGeometry::GetNormals() const {
|
||||||
const std::vector<unsigned int>& ShapeGeometry::GetIndices() const {
|
const std::vector<unsigned int>& ShapeGeometry::GetIndices() const {
|
||||||
return m_indices;
|
return m_indices;
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
LineGeometry::LineGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
|
: Geometry(id, element, name, doc)
|
||||||
|
{
|
||||||
|
const Scope* sc = element.Compound();
|
||||||
|
if (!sc) {
|
||||||
|
DOMError("failed to read Geometry object (class: Line), no data scope found");
|
||||||
|
}
|
||||||
|
const Element& Points = GetRequiredElement(*sc, "Points", &element);
|
||||||
|
const Element& PointsIndex = GetRequiredElement(*sc, "PointsIndex", &element);
|
||||||
|
ParseVectorDataArray(m_vertices, Points);
|
||||||
|
ParseVectorDataArray(m_indices, PointsIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
LineGeometry::~LineGeometry() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
const std::vector<aiVector3D>& LineGeometry::GetVertices() const {
|
||||||
|
return m_vertices;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
const std::vector<int>& LineGeometry::GetIndices() const {
|
||||||
|
return m_indices;
|
||||||
|
}
|
||||||
} // !FBX
|
} // !FBX
|
||||||
} // !Assimp
|
} // !Assimp
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -205,6 +205,28 @@ private:
|
||||||
std::vector<aiVector3D> m_normals;
|
std::vector<aiVector3D> m_normals;
|
||||||
std::vector<unsigned int> m_indices;
|
std::vector<unsigned int> m_indices;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* DOM class for FBX geometry of type "Line"
|
||||||
|
*/
|
||||||
|
class LineGeometry : public Geometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** The class constructor */
|
||||||
|
LineGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
|
|
||||||
|
/** The class destructor */
|
||||||
|
virtual ~LineGeometry();
|
||||||
|
|
||||||
|
/** Get a list of all vertex points, non-unique*/
|
||||||
|
const std::vector<aiVector3D>& GetVertices() const;
|
||||||
|
|
||||||
|
/** Return list of vertex indices. */
|
||||||
|
const std::vector<int>& GetIndices() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<aiVector3D> m_vertices;
|
||||||
|
std::vector<int> m_indices;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue