ColorIndex supported now for vertex colors.
Other properties should index override where appropriate in future.
This commit is contained in:
parent
ee903becc8
commit
8ffad0d8bd
4 changed files with 122 additions and 16 deletions
|
@ -172,13 +172,14 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
|
||||||
&collect_all,
|
&collect_all,
|
||||||
HashMap<int, Vector2>());
|
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(),
|
vertices.size(),
|
||||||
mesh_geometry->get_edge_map(),
|
mesh_geometry->get_edge_map(),
|
||||||
polygon_indices,
|
polygon_indices,
|
||||||
mesh_geometry->get_colors(),
|
mesh_geometry->get_colors(),
|
||||||
&collect_first,
|
&collect_all,
|
||||||
Color());
|
HashMap<int, Color>());
|
||||||
|
|
||||||
// TODO what about tangents?
|
// TODO what about tangents?
|
||||||
// TODO what about bi-nomials?
|
// TODO what about bi-nomials?
|
||||||
|
@ -209,15 +210,21 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
|
||||||
colors,
|
colors,
|
||||||
morphs,
|
morphs,
|
||||||
normals_raw,
|
normals_raw,
|
||||||
|
colors_raw,
|
||||||
uvs_0_raw,
|
uvs_0_raw,
|
||||||
uvs_1_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.
|
// 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
|
// This is a safety step, because the mesh_geometry data are no more valid
|
||||||
// at this point.
|
// at this point.
|
||||||
|
|
||||||
const int vertex_count = vertices.size();
|
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.
|
// The map key is the material allocator id that is also used as surface id.
|
||||||
HashMap<SurfaceId, SurfaceData> surfaces;
|
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) {
|
for (size_t polygon_vertex = 0; polygon_vertex < polygon_indices.size(); polygon_vertex += 1) {
|
||||||
if (is_start_of_polygon(polygon_indices, polygon_vertex)) {
|
if (is_start_of_polygon(polygon_indices, polygon_vertex)) {
|
||||||
polygon_index += 1;
|
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_id = polygon_surfaces[polygon_index];
|
||||||
surface_data = surfaces.getptr(surface_id);
|
surface_data = surfaces.getptr(surface_id);
|
||||||
CRASH_COND(surface_data == nullptr); // Can't be null.
|
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)) {
|
for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) {
|
||||||
SurfaceData *surface = surfaces.getptr(*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->add_surface_from_arrays(
|
||||||
Mesh::PRIMITIVE_TRIANGLES,
|
Mesh::PRIMITIVE_TRIANGLES,
|
||||||
|
@ -496,6 +506,7 @@ void FBXMeshData::reorganize_vertices(
|
||||||
HashMap<int, Color> &r_color,
|
HashMap<int, Color> &r_color,
|
||||||
HashMap<String, MorphVertexData> &r_morphs,
|
HashMap<String, MorphVertexData> &r_morphs,
|
||||||
HashMap<int, HashMap<int, Vector3> > &r_normals_raw,
|
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_1_raw,
|
||||||
HashMap<int, HashMap<int, Vector2> > &r_uv_2_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_uv1 = Vector2();
|
||||||
Vector2 this_vert_poly_uv2 = Vector2();
|
Vector2 this_vert_poly_uv2 = Vector2();
|
||||||
Vector3 this_vert_poly_normal = Vector3();
|
Vector3 this_vert_poly_normal = Vector3();
|
||||||
|
Color this_vert_poly_color = Color();
|
||||||
|
|
||||||
// Take the normal and see if we need to duplicate this polygon.
|
// Take the normal and see if we need to duplicate this polygon.
|
||||||
if (r_normals_raw.has(index)) {
|
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.
|
// 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;
|
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_uv1 = false;
|
||||||
bool same_uv2 = false;
|
bool same_uv2 = false;
|
||||||
bool same_normal = false;
|
bool same_normal = false;
|
||||||
|
bool same_color = false;
|
||||||
|
|
||||||
if (r_uv_1.has(new_vertex)) {
|
if (r_uv_1.has(new_vertex)) {
|
||||||
if ((this_vert_poly_uv1 - (*r_uv_1.getptr(new_vertex))).length_squared() <= CMP_EPSILON) {
|
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 (r_normals.has(new_vertex)) {
|
||||||
if ((this_vert_poly_normal - (*r_normals.getptr(new_vertex))).length_squared() <= CMP_EPSILON) {
|
if ((this_vert_poly_normal - (*r_normals.getptr(new_vertex))).length_squared() <= CMP_EPSILON) {
|
||||||
same_uv2 = true;
|
same_uv2 = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (same_uv1 && same_uv2 && same_normal) {
|
if (same_uv1 && same_uv2 && same_normal && same_color) {
|
||||||
similar_vertex = new_vertex;
|
similar_vertex = new_vertex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -636,6 +690,8 @@ void FBXMeshData::reorganize_vertices(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
need_duplication = false;
|
||||||
|
|
||||||
if (need_duplication) {
|
if (need_duplication) {
|
||||||
const Vertex old_index = index;
|
const Vertex old_index = index;
|
||||||
const Vertex new_index = r_vertices.size();
|
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;
|
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
|
// UV 0
|
||||||
if (r_uv_1_raw.has(old_index)) {
|
if (r_uv_1_raw.has(old_index)) {
|
||||||
r_uv_1.set(new_index, this_vert_poly_uv1);
|
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;
|
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
|
// Morphs
|
||||||
for (const String *mname = r_morphs.next(nullptr); mname != nullptr; mname = r_morphs.next(mname)) {
|
for (const String *mname = r_morphs.next(nullptr); mname != nullptr; mname = r_morphs.next(mname)) {
|
||||||
MorphVertexData *d = r_morphs.getptr(*mname);
|
MorphVertexData *d = r_morphs.getptr(*mname);
|
||||||
|
@ -700,6 +758,10 @@ void FBXMeshData::reorganize_vertices(
|
||||||
r_normals.set(index, this_vert_poly_normal);
|
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) &&
|
if (r_uv_1_raw.has(index) &&
|
||||||
r_uv_1.has(index) == false) {
|
r_uv_1.has(index) == false) {
|
||||||
r_uv_1.set(index, this_vert_poly_uv1);
|
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)
|
* data size is 96 (contains uv coordinates)
|
||||||
* this means index is simple data reduction basically
|
* 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");
|
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.
|
// Aggregate vertex data.
|
||||||
|
|
|
@ -108,6 +108,7 @@ private:
|
||||||
HashMap<int, Color> &r_color,
|
HashMap<int, Color> &r_color,
|
||||||
HashMap<String, MorphVertexData> &r_morphs,
|
HashMap<String, MorphVertexData> &r_morphs,
|
||||||
HashMap<int, HashMap<int, Vector3> > &r_normals_raw,
|
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_1_raw,
|
||||||
HashMap<int, HashMap<int, Vector2> > &r_uv_2_raw);
|
HashMap<int, HashMap<int, Vector2> > &r_uv_2_raw);
|
||||||
|
|
||||||
|
|
|
@ -211,7 +211,33 @@ MeshGeometry::MeshGeometry(uint64_t id, const ElementPtr element, const std::str
|
||||||
} else if (layer_type_name == "LayerElementNormal") {
|
} else if (layer_type_name == "LayerElementNormal") {
|
||||||
m_normals = resolve_vertex_data_array<Vector3>(layer_scope, MappingInformationType, ReferenceInformationType, "Normals");
|
m_normals = resolve_vertex_data_array<Vector3>(layer_scope, MappingInformationType, ReferenceInformationType, "Normals");
|
||||||
} else if (layer_type_name == "LayerElementColor") {
|
} 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 ScopePtr source,
|
||||||
const std::string &MappingInformationType,
|
const std::string &MappingInformationType,
|
||||||
const std::string &ReferenceInformationType,
|
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");
|
ERR_FAIL_COND_V_MSG(source == nullptr, MappingData<T>(), "Invalid scope operator preventing memory corruption");
|
||||||
|
|
||||||
// UVIndex, MaterialIndex, NormalIndex, etc..
|
// 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
|
// goal: expand everything to be per vertex
|
||||||
|
|
||||||
ReferenceType l_ref_type = ReferenceType::direct;
|
ReferenceType l_ref_type = ReferenceType::direct;
|
||||||
|
|
|
@ -207,7 +207,8 @@ private:
|
||||||
const ScopePtr source,
|
const ScopePtr source,
|
||||||
const std::string &MappingInformationType,
|
const std::string &MappingInformationType,
|
||||||
const std::string &ReferenceInformationType,
|
const std::string &ReferenceInformationType,
|
||||||
const std::string &dataElementName);
|
const std::string &dataElementName,
|
||||||
|
const std::string &indexOverride = "");
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue