Не удалось загрузить сетки FBX с правильным преобразованием. Assimp 5.2.5C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Не удалось загрузить сетки FBX с правильным преобразованием. Assimp 5.2.5

Сообщение Anonymous »

Я экспортировал модель в формат FBX внутри 3DS Max. Внутри Макса сцена выглядит следующим образом:

< /p>
Когда я импортирую его в своем программном обеспечении, я получаю это:

/>
Преобразование сетки неверно. Но если я импортирую файл Max FBX внутри Blender, то я экспортирую оттуда, я понимаю его правильно :


Здесь загружается модель:

Код: Выделить всё

void BaseModel::loadAssimpModel(const std::wstring& path)
{
// Read file via ASSIMP
aiPropertyStore* props = aiCreatePropertyStore();
aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, MAX_TRIANGLES_PER_MESH);

const uint32_t flags = aiProcess_Triangulate | aiProcess_CalcTangentSpace;
const std::string pathStr = Utilities::nativeStringToStdString(path);
const aiScene* scene = aiImportFileExWithProperties(pathStr.c_str(), flags, NULL, props);

aiReleasePropertyStore(props);

// Check for errors
const nbBool success = scene && scene->mFlags != AI_SCENE_FLAGS_INCOMPLETE && scene->mRootNode;
assert(success);

// Process ASSIMP's root node recursively here !!! :)
processNode(scene, scene->mRootNode, aiMatrix4x4());

aiReleaseImport(scene);
}
метод процесса проста:

Код: Выделить всё

void BaseModel::processNode(const aiScene* scene, aiNode* node, const aiMatrix4x4& transform)
{
const aiMatrix4x4 accTransform = node->mTransformation * transform;

// Process each mesh located at the current node.
if (node->mNumMeshes)
{
// Create group.
DatabaseMeshPtr meshGroup;
{
aiMesh* firstMesh = scene->mMeshes[node->mMeshes[0]];

std::wstring groupName(Utilities::stdStringToNativeString(firstMesh->mName.C_Str()));

meshGroup = EntityDatabaseSingleton::instance()->createEntity();
meshGroup->setName(groupName);

meshGroup->m_materialId = m_aiLoadingMaterialIds[firstMesh->mMaterialIndex];

m_meshGroupIdentifiers.push_back(meshGroup->getIdentifier());
}

// Add meshes.
for (uint32_t i = 0; i < node->mNumMeshes; i++)
{
// The node object only contains indices to index the actual objects in the scene.
// The scene contains all the data, node is just to keep stuff organized (like relations between nodes).
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
this->addMesh(mesh, accTransform, meshGroup);
}
}

// After we've processed all of the meshes (if any) we then recursively process each of the children nodes
for (uint32_t i = 0; i < node->mNumChildren; i++)
{
this->processNode(scene, node->mChildren[i], accTransform);
}
}
Метод AddMesh:

Код: Выделить всё

void BaseModel::addMesh(aiMesh* mesh, const aiMatrix4x4& transform, DatabaseMeshPtr meshGroup)
{
// Data to fill
VertexArray vertices;
std::vector indices;

// The 3x3 transform.
const aiMatrix3x3 transform3x3 = aiMatrix3x3(transform);

// Walk through each of the mesh's vertices
for (uint32_t i = 0; i < mesh->mNumVertices; i++)
{
FullVertex vertex;

mesh->mVertices[i] = transform * mesh->mVertices[i];

// Position
vertex.position.x = mesh->mVertices[i].x;
vertex.position.y = mesh->mVertices[i].y;
vertex.position.z = mesh->mVertices[i].z;

// Normal.
if (mesh->mNormals)
{
mesh->mNormals[i] = transform3x3 * mesh->mNormals[i];

vertex.normal.x = mesh->mNormals[i].x;
vertex.normal.y = mesh->mNormals[i].y;
vertex.normal.z = mesh->mNormals[i].z;
}

// Tangent
if (mesh->mTangents)
{
vertex.tangent.x = mesh->mTangents[i].x;
vertex.tangent.y = mesh->mTangents[i].y;
vertex.tangent.z = mesh->mTangents[i].z;
}

// Bitangent
if (mesh->mBitangents)
{
vertex.bitangent.x = mesh->mBitangents[i].x;
vertex.bitangent.y = mesh->mBitangents[i].y;
vertex.bitangent.z = mesh->mBitangents[i].z;
}

// Texture Coordinates
if (mesh->mTextureCoords[0]) // Does the mesh contain texture coordinates?
{
// A vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
// use models where a vertex can have multiple texture coordinates so we always take the first set (0).
vertex.texCoord.x = mesh->mTextureCoords[0][i].x;
vertex.texCoord.y = mesh->mTextureCoords[0][i].y;
}

vertices.push_back(vertex);
}

// Now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
for (uint32_t i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
// Retrieve all indices of the face and store them in the indices vector
for (uint32_t j = 0; j < face.mNumIndices; j++)
indices.push_back(face.mIndices[j]);
}

const MeshFlatId meshFlatId = (MeshFlatId)m_flatMeshContainer.size();

Mesh* nativeMesh = new Mesh(vertices, indices, meshFlatId, meshGroup.get());

meshGroup->m_meshes.push_back(nativeMesh);
m_flatMeshContainer.push_back(nativeMesh);
}
< /code>
После того, как загрузка выполняется вершины, преобразуются в локальное пространство. Я не думаю, что это связано с проблемой: < /p>
for (const EntityIdentifier& entityId : m_meshGroupIdentifiers)
{
Math::Vec3 center;
size_t nbVertices = 0u;

const auto group = getMeshGroupPtr_FromEntity(entityId);

for (const auto*mesh : group->m_meshes)
{
const auto& vertices = mesh->getRealVertices();
for (auto& vertex : vertices)
center += vertex.position;

nbVertices += vertices.size();
}

center /= nbVertices;
for (auto* mesh : group->m_meshes)
{
auto& vertices = mesh->getMutableVertices();
for (auto& vertex : vertices)
vertex.position -= center;
}

group->setPosition(center);
}
Последний setposition вызов установил преобразование Worlspace группы сетки. Он используется при выполнении рендеринга DirectX 12 в реальном времени: < /p>
cbuffer VertexShaderSharedCB : register(b0)
{
float4x4 vpMat;
};

VS_OUTPUT main(VS_INPUT input, uint instanceID : SV_InstanceID)
{
VS_OUTPUT output;

const float4x4 modelMat = meshGroupDatas[instanceID].transform;// transform here!
const float4 worldPosition = mul(float4(input.position, 1.0f), modelMat);
output.worldPosition = worldPosition.xyz;
output.position = mul(worldPosition, vpMat);
output.texCoord = input.texCoord;
output.normal = normalize(mul(float4(input.normal, 0.0f), modelMat));
output.tangent = normalize(mul(float4(input.tangent, 0.0f), modelMat));
output.bitangent = normalize(mul(float4(input.bitangent, 0.0f), modelMat));

return output;
}
< /code>
Что я делаю не так? И особенно почему Blender FBX загружается должным образом, а не 3DS Max One? Я, наверное, где -то упускаю преобразование. Обратите внимание, что objs всегда правильно загружаются;) < /strong> < /p>
Спасибо!

// -----------------------------------------------------------------------------

MAX-файл:

https://www.dropbox.com/scl/fi/5rus8jyh ... ender/file />
https://www.dropbox.com/scl/fi/zv9slsjz ... jn6&dl=0,P.>

Подробнее здесь: https://stackoverflow.com/questions/796 ... simp-5-2-5
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»