Fix import rotation and UVs
parent
e87c629406
commit
dd74b361e3
|
|
@ -111,6 +111,7 @@ public:
|
|||
bool mCacheOnlyHitIfRigged; // ignore cached SLM if it does not contain rig info (and we want rig info)
|
||||
|
||||
model_list mModelList;
|
||||
// The scene is pretty much what ends up getting loaded for upload. Basically assign things to this guy if you want something uploaded.
|
||||
scene mScene;
|
||||
|
||||
typedef std::queue<LLPointer<LLModel> > model_queue;
|
||||
|
|
|
|||
|
|
@ -153,15 +153,20 @@ bool LLGLTFLoader::parseMeshes()
|
|||
{
|
||||
LLModel* pModel = new LLModel(volume_params, 0.f);
|
||||
auto mesh = mGLTFAsset.mMeshes[meshidx];
|
||||
if (populateModelFromMesh(pModel, mesh, mats) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel))
|
||||
if (populateModelFromMesh(pModel, mesh, node, mats) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel))
|
||||
{
|
||||
mModelList.push_back(pModel);
|
||||
LLMatrix4 saved_transform = mTransform;
|
||||
|
||||
LLMatrix4 gltf_transform = LLMatrix4(glm::value_ptr(node.mMatrix));
|
||||
|
||||
mTransform *= gltf_transform;
|
||||
mTransform.condition();
|
||||
|
||||
// GLTF is +Y up, SL is +Z up
|
||||
LLMatrix4 rotation;
|
||||
rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f);
|
||||
mTransform *= rotation;
|
||||
|
||||
transformation = mTransform;
|
||||
// adjust the transformation to compensate for mesh normalization
|
||||
LLVector3 mesh_scale_vector;
|
||||
|
|
@ -206,7 +211,7 @@ bool LLGLTFLoader::parseMeshes()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map &mats)
|
||||
bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh& mesh, const LL::GLTF::Node& node, material_map& mats)
|
||||
{
|
||||
pModel->mLabel = mesh.mName;
|
||||
pModel->ClearFacesAndMaterials();
|
||||
|
|
@ -222,10 +227,10 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &
|
|||
// count. Just go ahead and populate faces direct from the GLTF primitives here. -Geenz 2025-04-07
|
||||
LLVolumeFace face;
|
||||
LLVolumeFace::VertexMapData::PointMap point_map;
|
||||
|
||||
|
||||
std::vector<GLTFVertex> vertices;
|
||||
std::vector<U16> indices;
|
||||
|
||||
|
||||
LLImportMaterial impMat;
|
||||
|
||||
LL::GLTF::Material* material = nullptr;
|
||||
|
|
@ -240,7 +245,7 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &
|
|||
GLTFVertex vert;
|
||||
vert.position = glm::vec3(prim.mPositions[i][0], prim.mPositions[i][1], prim.mPositions[i][2]);
|
||||
vert.normal = glm::vec3(prim.mNormals[i][0], prim.mNormals[i][1], prim.mNormals[i][2]);
|
||||
vert.uv0 = glm::vec2(prim.mTexCoords0[i][0], prim.mTexCoords0[i][1]);
|
||||
vert.uv0 = glm::vec2(prim.mTexCoords0[i][0],-prim.mTexCoords0[i][1]);
|
||||
vertices.push_back(vert);
|
||||
}
|
||||
|
||||
|
|
@ -250,12 +255,29 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &
|
|||
}
|
||||
|
||||
std::vector<LLVolumeFace::VertexData> faceVertices;
|
||||
|
||||
glm::vec3 min = glm::vec3(0);
|
||||
glm::vec3 max = glm::vec3(0);
|
||||
for (U32 i = 0; i < vertices.size(); i++)
|
||||
{
|
||||
LLVolumeFace::VertexData vert;
|
||||
LLVector4a position = LLVector4a(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z);
|
||||
LLVector4a normal = LLVector4a(vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z);
|
||||
|
||||
if (vertices[i].position.x > max.x)
|
||||
max.x = vertices[i].position.x;
|
||||
if (vertices[i].position.y > max.y)
|
||||
max.y = vertices[i].position.y;
|
||||
if (vertices[i].position.z > max.z)
|
||||
max.z = vertices[i].position.z;
|
||||
|
||||
|
||||
if (vertices[i].position.x < min.x)
|
||||
min.x = vertices[i].position.x;
|
||||
if (vertices[i].position.y < min.y)
|
||||
min.y = vertices[i].position.y;
|
||||
if (vertices[i].position.z < min.z)
|
||||
min.z = vertices[i].position.z;
|
||||
|
||||
LLVector4a position = LLVector4a(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z);
|
||||
LLVector4a normal = LLVector4a(vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z);
|
||||
vert.setPosition(position);
|
||||
vert.setNormal(normal);
|
||||
vert.mTexCoord = LLVector2(vertices[i].uv0.x, vertices[i].uv0.y);
|
||||
|
|
@ -263,6 +285,8 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &
|
|||
}
|
||||
|
||||
face.fillFromLegacyData(faceVertices, indices);
|
||||
face.mExtents[0] = LLVector4a(min.x, min.y, min.z, 0);
|
||||
face.mExtents[1] = LLVector4a(max.x, max.y, max.z, 0);
|
||||
|
||||
pModel->getVolumeFaces().push_back(face);
|
||||
pModel->getMaterialList().push_back("mat" + std::to_string(prim.mMaterial));
|
||||
|
|
@ -280,205 +304,6 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
LLModel::EModelStatus loadFaceFromGLTFModel(LLModel* pModel, const LL::GLTF::Mesh& mesh, material_map& mats, LLSD& log_msg)
|
||||
{
|
||||
LLVolumeFace face;
|
||||
std::vector<LLVolumeFace::VertexData> verts;
|
||||
std::vector<U16> indices;
|
||||
|
||||
S32 pos_offset = -1;
|
||||
S32 tc_offset = -1;
|
||||
S32 norm_offset = -1;
|
||||
|
||||
auto pos_source = mesh.mPrimitives[0].mPositions;
|
||||
auto tc_source = mesh.mPrimitives[0].mNormals;
|
||||
auto norm_source = mesh.mPrimitives[0].mTexCoords0;
|
||||
|
||||
S32 idx_stride = 0;
|
||||
|
||||
if (pos_source.size() > USHRT_MAX)
|
||||
{
|
||||
LL_WARNS() << "Unable to process mesh due to 16-bit index limits; invalid model; invalid model." << LL_ENDL;
|
||||
LLSD args;
|
||||
args["Message"] = "ParsingErrorBadElement";
|
||||
log_msg.append(args);
|
||||
return LLModel::BAD_ELEMENT;
|
||||
|
||||
}
|
||||
|
||||
std::vector<U32> idx = mesh.mPrimitives[0].mIndexArray;
|
||||
|
||||
domListOfFloats dummy;
|
||||
domListOfFloats& v = pos_source ? pos_source->getFloat_array()->getValue() : dummy;
|
||||
domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy;
|
||||
domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy;
|
||||
|
||||
if (pos_source.size() == 0)
|
||||
{
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
// VFExtents change
|
||||
face.mExtents[0].set(pos_source[0][0], pos_source[0][1], pos_source[0][2]);
|
||||
face.mExtents[1].set(pos_source[0][0], pos_source[0][1], pos_source[0][2]);
|
||||
|
||||
LLVolumeFace::VertexMapData::PointMap point_map;
|
||||
|
||||
if (idx_stride <= 0 || (pos_source && pos_offset >= idx_stride) || (tc_source && tc_offset >= idx_stride) ||
|
||||
(norm_source && norm_offset >= idx_stride))
|
||||
{
|
||||
// Looks like these offsets should fit inside idx_stride
|
||||
// Might be good idea to also check idx.getCount()%idx_stride != 0
|
||||
LL_WARNS() << "Invalid pos_offset " << pos_offset << ", tc_offset " << tc_offset << " or norm_offset " << norm_offset << LL_ENDL;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < idx.getCount(); i += idx_stride)
|
||||
{
|
||||
LLVolumeFace::VertexData cv;
|
||||
if (pos_source)
|
||||
{
|
||||
cv.setPosition(
|
||||
LLVector4a((F32)v[idx[i + pos_offset] * 3 + 0], (F32)v[idx[i + pos_offset] * 3 + 1], (F32)v[idx[i + pos_offset] * 3 + 2]));
|
||||
}
|
||||
|
||||
if (tc_source)
|
||||
{
|
||||
cv.mTexCoord.setVec((F32)tc[idx[i + tc_offset] * 2 + 0], (F32)tc[idx[i + tc_offset] * 2 + 1]);
|
||||
}
|
||||
|
||||
if (norm_source)
|
||||
{
|
||||
cv.setNormal(LLVector4a((F32)n[idx[i + norm_offset] * 3 + 0],
|
||||
(F32)n[idx[i + norm_offset] * 3 + 1],
|
||||
(F32)n[idx[i + norm_offset] * 3 + 2]));
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
LLVolumeFace::VertexMapData::PointMap::iterator point_iter;
|
||||
point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr()));
|
||||
|
||||
if (point_iter != point_map.end())
|
||||
{
|
||||
for (U32 j = 0; j < point_iter->second.size(); ++j)
|
||||
{
|
||||
// We have a matching loc
|
||||
//
|
||||
if ((point_iter->second)[j] == cv)
|
||||
{
|
||||
U16 shared_index = (point_iter->second)[j].mIndex;
|
||||
|
||||
// Don't share verts within the same tri, degenerate
|
||||
//
|
||||
U32 indx_size = static_cast<U32>(indices.size());
|
||||
U32 verts_new_tri = indx_size % 3;
|
||||
if ((verts_new_tri < 1 || indices[indx_size - 1] != shared_index) &&
|
||||
(verts_new_tri < 2 || indices[indx_size - 2] != shared_index))
|
||||
{
|
||||
found = true;
|
||||
indices.push_back(shared_index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// VFExtents change
|
||||
update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());
|
||||
verts.push_back(cv);
|
||||
if (verts.size() >= 65535)
|
||||
{
|
||||
// llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL;
|
||||
return LLModel::VERTEX_NUMBER_OVERFLOW;
|
||||
}
|
||||
U16 index = (U16)(verts.size() - 1);
|
||||
indices.push_back(index);
|
||||
|
||||
LLVolumeFace::VertexMapData d;
|
||||
d.setPosition(cv.getPosition());
|
||||
d.mTexCoord = cv.mTexCoord;
|
||||
d.setNormal(cv.getNormal());
|
||||
d.mIndex = index;
|
||||
if (point_iter != point_map.end())
|
||||
{
|
||||
point_iter->second.push_back(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
if (indices.size() % 3 == 0 && verts.size() >= 65532)
|
||||
{
|
||||
std::string material;
|
||||
|
||||
if (tri->getMaterial())
|
||||
{
|
||||
material = std::string(tri->getMaterial());
|
||||
}
|
||||
|
||||
materials.push_back(material);
|
||||
face_list.push_back(face);
|
||||
face_list.rbegin()->fillFromLegacyData(verts, indices);
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
// ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
// ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
face = LLVolumeFace();
|
||||
// VFExtents change
|
||||
face.mExtents[0].set((F32)v[0], (F32)v[1], (F32)v[2]);
|
||||
face.mExtents[1].set((F32)v[0], (F32)v[1], (F32)v[2]);
|
||||
|
||||
verts.clear();
|
||||
indices.clear();
|
||||
point_map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (!verts.empty())
|
||||
{
|
||||
std::string material;
|
||||
|
||||
if (tri->getMaterial())
|
||||
{
|
||||
material = std::string(tri->getMaterial());
|
||||
}
|
||||
|
||||
materials.push_back(material);
|
||||
face_list.push_back(face);
|
||||
|
||||
face_list.rbegin()->fillFromLegacyData(verts, indices);
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
// ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
// ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return LLModel::NO_ERRORS;
|
||||
}
|
||||
*/
|
||||
bool LLGLTFLoader::parseMaterials()
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ private:
|
|||
void uploadMeshes();
|
||||
bool parseMaterials();
|
||||
void uploadMaterials();
|
||||
bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map& mats);
|
||||
bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats);
|
||||
LLUUID imageBufferToTextureUUID(const gltf_texture& tex);
|
||||
|
||||
// bool mPreprocessGLTF;
|
||||
|
|
|
|||
Loading…
Reference in New Issue