ColorIndex supported now for vertex colors.

Other properties should index override where appropriate in future.
This commit is contained in:
Gordon MacPherson 2020-12-14 16:50:46 +00:00
parent ee903becc8
commit 8ffad0d8bd
4 changed files with 122 additions and 16 deletions

View file

@ -172,13 +172,14 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
&collect_all,
HashMap<int, Vector2>());
HashMap<int, Color> colors = extract_per_vertex_data(
HashMap<int, Color> colors;
HashMap<int, HashMap<int, Color> > colors_raw = extract_per_vertex_data(
vertices.size(),
mesh_geometry->get_edge_map(),
polygon_indices,
mesh_geometry->get_colors(),
&collect_first,
Color());
&collect_all,
HashMap<int, Color>());
// TODO what about tangents?
// TODO what about bi-nomials?
@ -209,15 +210,21 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
colors,
morphs,
normals_raw,
colors_raw,
uvs_0_raw,
uvs_1_raw);
const int color_count = colors.size();
print_verbose("Vertex color count: " + itos(color_count));
// Make sure that from this moment on the mesh_geometry is no used anymore.
// This is a safety step, because the mesh_geometry data are no more valid
// at this point.
const int vertex_count = vertices.size();
print_verbose("Vertex count: " + itos(vertex_count));
// The map key is the material allocator id that is also used as surface id.
HashMap<SurfaceId, SurfaceData> surfaces;
@ -267,7 +274,7 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
for (size_t polygon_vertex = 0; polygon_vertex < polygon_indices.size(); polygon_vertex += 1) {
if (is_start_of_polygon(polygon_indices, polygon_vertex)) {
polygon_index += 1;
ERR_FAIL_COND_V_MSG(polygon_surfaces.has(polygon_index) == false, nullptr, "The FBX file is currupted, This surface_index is not expected.");
ERR_FAIL_COND_V_MSG(polygon_surfaces.has(polygon_index) == false, nullptr, "The FBX file is corrupted, This surface_index is not expected.");
surface_id = polygon_surfaces[polygon_index];
surface_data = surfaces.getptr(surface_id);
CRASH_COND(surface_data == nullptr); // Can't be null.
@ -385,7 +392,10 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) {
SurfaceData *surface = surfaces.getptr(*surface_id);
surface->surface_tool->generate_tangents();
// you can't generate them without a valid uv map.
if (uvs_0_raw.size() > 0) {
surface->surface_tool->generate_tangents();
}
mesh->add_surface_from_arrays(
Mesh::PRIMITIVE_TRIANGLES,
@ -496,6 +506,7 @@ void FBXMeshData::reorganize_vertices(
HashMap<int, Color> &r_color,
HashMap<String, MorphVertexData> &r_morphs,
HashMap<int, HashMap<int, Vector3> > &r_normals_raw,
HashMap<int, HashMap<int, Color> > &r_colors_raw,
HashMap<int, HashMap<int, Vector2> > &r_uv_1_raw,
HashMap<int, HashMap<int, Vector2> > &r_uv_2_raw) {
@ -513,6 +524,7 @@ void FBXMeshData::reorganize_vertices(
Vector2 this_vert_poly_uv1 = Vector2();
Vector2 this_vert_poly_uv2 = Vector2();
Vector3 this_vert_poly_normal = Vector3();
Color this_vert_poly_color = Color();
// Take the normal and see if we need to duplicate this polygon.
if (r_normals_raw.has(index)) {
@ -548,6 +560,41 @@ void FBXMeshData::reorganize_vertices(
}
}
// TODO: make me vertex color
// Take the normal and see if we need to duplicate this polygon.
if (r_colors_raw.has(index)) {
const HashMap<PolygonId, Color> *color_arr = r_colors_raw.getptr(index);
if (color_arr->has(polygon_index)) {
this_vert_poly_color = color_arr->get(polygon_index);
} else if (color_arr->has(-1)) {
this_vert_poly_color = color_arr->get(-1);
} else {
print_error("invalid color detected: " + itos(index) + " polygon index: " + itos(polygon_index));
for (const PolygonId *pid = color_arr->next(nullptr); pid != nullptr; pid = color_arr->next(pid)) {
print_verbose("debug contents key: " + itos(*pid));
if (color_arr->has(*pid)) {
print_verbose("contents valid: " + color_arr->get(*pid));
}
}
}
// Now, check if we need to duplicate it.
for (const PolygonId *pid = color_arr->next(nullptr); pid != nullptr; pid = color_arr->next(pid)) {
if (*pid == polygon_index) {
continue;
}
const Color vert_poly_color = *color_arr->getptr(*pid);
if (!this_vert_poly_color.is_equal_approx(vert_poly_color)) {
// Yes this polygon need duplication.
need_duplication = true;
break;
}
}
}
// Take the UV1 and UV2 and see if we need to duplicate this polygon.
{
HashMap<int, HashMap<int, Vector2> > *uv_raw = &r_uv_1_raw;
@ -599,6 +646,7 @@ void FBXMeshData::reorganize_vertices(
bool same_uv1 = false;
bool same_uv2 = false;
bool same_normal = false;
bool same_color = false;
if (r_uv_1.has(new_vertex)) {
if ((this_vert_poly_uv1 - (*r_uv_1.getptr(new_vertex))).length_squared() <= CMP_EPSILON) {
@ -612,13 +660,19 @@ void FBXMeshData::reorganize_vertices(
}
}
if (r_color.has(new_vertex)) {
if (this_vert_poly_color.is_equal_approx((*r_color.getptr(new_vertex)))) {
same_color = true;
}
}
if (r_normals.has(new_vertex)) {
if ((this_vert_poly_normal - (*r_normals.getptr(new_vertex))).length_squared() <= CMP_EPSILON) {
same_uv2 = true;
}
}
if (same_uv1 && same_uv2 && same_normal) {
if (same_uv1 && same_uv2 && same_normal && same_color) {
similar_vertex = new_vertex;
break;
}
@ -636,6 +690,8 @@ void FBXMeshData::reorganize_vertices(
}
}
need_duplication = false;
if (need_duplication) {
const Vertex old_index = index;
const Vertex new_index = r_vertices.size();
@ -657,6 +713,13 @@ void FBXMeshData::reorganize_vertices(
r_normals_raw[new_index][polygon_index] = this_vert_poly_normal;
}
// Vertex Color
if (r_colors_raw.has(old_index)) {
r_color.set(new_index, this_vert_poly_color);
r_colors_raw.getptr(old_index)->erase(polygon_index);
r_colors_raw[new_index][polygon_index] = this_vert_poly_color;
}
// UV 0
if (r_uv_1_raw.has(old_index)) {
r_uv_1.set(new_index, this_vert_poly_uv1);
@ -671,11 +734,6 @@ void FBXMeshData::reorganize_vertices(
r_uv_2_raw[new_index][polygon_index] = this_vert_poly_uv2;
}
// Vertex color.
if (r_color.has(old_index)) {
r_color[new_index] = r_color[old_index];
}
// Morphs
for (const String *mname = r_morphs.next(nullptr); mname != nullptr; mname = r_morphs.next(mname)) {
MorphVertexData *d = r_morphs.getptr(*mname);
@ -700,6 +758,10 @@ void FBXMeshData::reorganize_vertices(
r_normals.set(index, this_vert_poly_normal);
}
if (r_colors_raw.has(index) && r_color.has(index) == false) {
r_color.set(index, this_vert_poly_color);
}
if (r_uv_1_raw.has(index) &&
r_uv_1.has(index) == false) {
r_uv_1.set(index, this_vert_poly_uv1);
@ -1010,8 +1072,14 @@ HashMap<int, R> FBXMeshData::extract_per_vertex_data(
* data size is 96 (contains uv coordinates)
* this means index is simple data reduction basically
*/
////
if (p_mapping_data.ref_type == FBXDocParser::MeshGeometry::ReferenceType::index_to_direct && p_mapping_data.index.size() == 0) {
print_verbose("debug count: index size: " + itos(p_mapping_data.index.size()) + ", data size: " + itos(p_mapping_data.data.size()));
print_verbose("vertex indices count: " + itos(p_mesh_indices.size()));
print_verbose("Edge map size: " + itos(p_edge_map.size()));
}
ERR_FAIL_COND_V_MSG(p_mapping_data.ref_type == FBXDocParser::MeshGeometry::ReferenceType::index_to_direct && p_mapping_data.index.size() == 0, (HashMap<int, R>()), "FBX file is missing indexing array");
ERR_FAIL_COND_V_MSG(p_mapping_data.ref_type == FBXDocParser::MeshGeometry::ReferenceType::index_to_direct && p_mapping_data.index.size() == 0, (HashMap<int, R>()), "FBX importer needs to map correctly to this field, please specify the override index name to fix this problem!");
ERR_FAIL_COND_V_MSG(p_mapping_data.ref_type == FBXDocParser::MeshGeometry::ReferenceType::index && p_mapping_data.index.size() == 0, (HashMap<int, R>()), "The FBX seems corrupted");
// Aggregate vertex data.

View file

@ -108,6 +108,7 @@ private:
HashMap<int, Color> &r_color,
HashMap<String, MorphVertexData> &r_morphs,
HashMap<int, HashMap<int, Vector3> > &r_normals_raw,
HashMap<int, HashMap<int, Color> > &r_colors_raw,
HashMap<int, HashMap<int, Vector2> > &r_uv_1_raw,
HashMap<int, HashMap<int, Vector2> > &r_uv_2_raw);

View file

@ -211,7 +211,33 @@ MeshGeometry::MeshGeometry(uint64_t id, const ElementPtr element, const std::str
} else if (layer_type_name == "LayerElementNormal") {
m_normals = resolve_vertex_data_array<Vector3>(layer_scope, MappingInformationType, ReferenceInformationType, "Normals");
} else if (layer_type_name == "LayerElementColor") {
m_colors = resolve_vertex_data_array<Color>(layer_scope, MappingInformationType, ReferenceInformationType, "Colors");
m_colors = resolve_vertex_data_array<Color>(layer_scope, MappingInformationType, ReferenceInformationType, "Colors", "ColorIndex");
// NOTE: this is a useful sanity check to ensure you're getting any color data which is not default.
// const Color first_color_check = m_colors.data[0];
// bool colors_are_all_the_same = true;
// size_t i = 1;
// for(i = 1; i < m_colors.data.size(); i++)
// {
// const Color current_color = m_colors.data[i];
// if(current_color.is_equal_approx(first_color_check))
// {
// continue;
// }
// else
// {
// colors_are_all_the_same = false;
// break;
// }
// }
//
// if(colors_are_all_the_same)
// {
// print_error("Color serialisation is not working for vertex colors some should be different in the test asset.");
// }
// else
// {
// print_verbose("Color array has unique colors at index: " + itos(i));
// }
}
}
}
@ -335,12 +361,22 @@ MeshGeometry::MappingData<T> MeshGeometry::resolve_vertex_data_array(
const ScopePtr source,
const std::string &MappingInformationType,
const std::string &ReferenceInformationType,
const std::string &dataElementName) {
const std::string &dataElementName,
const std::string &indexOverride) {
ERR_FAIL_COND_V_MSG(source == nullptr, MappingData<T>(), "Invalid scope operator preventing memory corruption");
// UVIndex, MaterialIndex, NormalIndex, etc..
std::string indexDataElementName = dataElementName + "Index";
std::string indexDataElementName;
if (indexOverride != "") {
// Colors should become ColorIndex
indexDataElementName = indexOverride;
} else {
// Some indexes will exist.
indexDataElementName = dataElementName + "Index";
}
// goal: expand everything to be per vertex
ReferenceType l_ref_type = ReferenceType::direct;

View file

@ -207,7 +207,8 @@ private:
const ScopePtr source,
const std::string &MappingInformationType,
const std::string &ReferenceInformationType,
const std::string &dataElementName);
const std::string &dataElementName,
const std::string &indexOverride = "");
};
/*