-Fixes to how collada generates tangents (use SurfaceTool), closes #9562
-Fix to gridmap cell size (wrong property type)
This commit is contained in:
parent
b2d53257ed
commit
a2027cfa49
4 changed files with 68 additions and 208 deletions
|
@ -41,6 +41,7 @@
|
|||
#include "scene/animation/animation_player.h"
|
||||
#include "scene/resources/animation.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -868,7 +869,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
int normal_pos = (normal_src->stride ? normal_src->stride : 3) * p.indices[src + normal_ofs];
|
||||
ERR_FAIL_INDEX_V(normal_pos, normal_src->array.size(), ERR_INVALID_DATA);
|
||||
vertex.normal = Vector3(normal_src->array[normal_pos + 0], normal_src->array[normal_pos + 1], normal_src->array[normal_pos + 2]);
|
||||
vertex.normal.snap(Vector3(0.001, 0.001, 0.001));
|
||||
|
||||
if (tangent_src && binormal_src) {
|
||||
|
||||
|
@ -991,18 +991,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
}
|
||||
}
|
||||
|
||||
PoolVector<int> index_array;
|
||||
index_array.resize(indices_list.size());
|
||||
PoolVector<int>::Write index_arrayw = index_array.write();
|
||||
|
||||
int iidx = 0;
|
||||
for (List<int>::Element *F = indices_list.front(); F; F = F->next()) {
|
||||
|
||||
index_arrayw[iidx++] = F->get();
|
||||
}
|
||||
|
||||
index_arrayw = PoolVector<int>::Write();
|
||||
|
||||
/*****************/
|
||||
/* MAKE SURFACES */
|
||||
/*****************/
|
||||
|
@ -1011,9 +999,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
|
||||
Ref<SpatialMaterial> material;
|
||||
|
||||
//find material
|
||||
Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
|
||||
|
||||
{
|
||||
|
||||
if (p_material_map.has(p.material)) {
|
||||
|
@ -1031,212 +1016,73 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
}
|
||||
}
|
||||
|
||||
PoolVector<Vector3> final_vertex_array;
|
||||
PoolVector<Vector3> final_normal_array;
|
||||
PoolVector<float> final_tangent_array;
|
||||
PoolVector<Color> final_color_array;
|
||||
PoolVector<Vector3> final_uv_array;
|
||||
PoolVector<Vector3> final_uv2_array;
|
||||
PoolVector<int> final_bone_array;
|
||||
PoolVector<float> final_weight_array;
|
||||
Ref<SurfaceTool> surftool;
|
||||
surftool.instance();
|
||||
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
|
||||
uint32_t final_format = 0;
|
||||
|
||||
//create format
|
||||
final_format = Mesh::ARRAY_FORMAT_VERTEX | Mesh::ARRAY_FORMAT_INDEX;
|
||||
|
||||
if (normal_src) {
|
||||
final_format |= Mesh::ARRAY_FORMAT_NORMAL;
|
||||
if (uv_src && binormal_src && tangent_src) {
|
||||
final_format |= Mesh::ARRAY_FORMAT_TANGENT;
|
||||
for (int k = 0; k < vertex_array.size(); k++) {
|
||||
if (normal_src) {
|
||||
surftool->add_normal(vertex_array[k].normal);
|
||||
if (binormal_src && tangent_src) {
|
||||
surftool->add_tangent(vertex_array[k].tangent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (color_src)
|
||||
final_format |= Mesh::ARRAY_FORMAT_COLOR;
|
||||
if (uv_src)
|
||||
final_format |= Mesh::ARRAY_FORMAT_TEX_UV;
|
||||
if (uv2_src)
|
||||
final_format |= Mesh::ARRAY_FORMAT_TEX_UV2;
|
||||
|
||||
if (has_weights) {
|
||||
final_format |= Mesh::ARRAY_FORMAT_WEIGHTS;
|
||||
final_format |= Mesh::ARRAY_FORMAT_BONES;
|
||||
}
|
||||
|
||||
//set arrays
|
||||
|
||||
int vlen = vertex_array.size();
|
||||
{ //vertices
|
||||
|
||||
PoolVector<Vector3> varray;
|
||||
varray.resize(vertex_array.size());
|
||||
|
||||
PoolVector<Vector3>::Write varrayw = varray.write();
|
||||
|
||||
for (int k = 0; k < vlen; k++)
|
||||
varrayw[k] = vertex_array[k].vertex;
|
||||
|
||||
varrayw = PoolVector<Vector3>::Write();
|
||||
final_vertex_array = varray;
|
||||
}
|
||||
|
||||
if (uv_src) { //compute uv first, may be needed for computing tangent/bionrmal
|
||||
PoolVector<Vector3> uvarray;
|
||||
uvarray.resize(vertex_array.size());
|
||||
PoolVector<Vector3>::Write uvarrayw = uvarray.write();
|
||||
|
||||
for (int k = 0; k < vlen; k++) {
|
||||
uvarrayw[k] = vertex_array[k].uv;
|
||||
if (uv_src) {
|
||||
surftool->add_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y));
|
||||
}
|
||||
if (uv2_src) {
|
||||
surftool->add_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y));
|
||||
}
|
||||
if (color_src) {
|
||||
surftool->add_color(vertex_array[k].color);
|
||||
}
|
||||
|
||||
uvarrayw = PoolVector<Vector3>::Write();
|
||||
final_uv_array = uvarray;
|
||||
}
|
||||
|
||||
if (uv2_src) { //compute uv first, may be needed for computing tangent/bionrmal
|
||||
PoolVector<Vector3> uv2array;
|
||||
uv2array.resize(vertex_array.size());
|
||||
PoolVector<Vector3>::Write uv2arrayw = uv2array.write();
|
||||
|
||||
for (int k = 0; k < vlen; k++) {
|
||||
uv2arrayw[k] = vertex_array[k].uv2;
|
||||
}
|
||||
|
||||
uv2arrayw = PoolVector<Vector3>::Write();
|
||||
final_uv2_array = uv2array;
|
||||
}
|
||||
|
||||
if (normal_src) {
|
||||
PoolVector<Vector3> narray;
|
||||
narray.resize(vertex_array.size());
|
||||
PoolVector<Vector3>::Write narrayw = narray.write();
|
||||
|
||||
for (int k = 0; k < vlen; k++) {
|
||||
narrayw[k] = vertex_array[k].normal;
|
||||
}
|
||||
|
||||
narrayw = PoolVector<Vector3>::Write();
|
||||
final_normal_array = narray;
|
||||
|
||||
/*
|
||||
PoolVector<Vector3> altnaray;
|
||||
_generate_normals(index_array,final_vertex_array,altnaray);
|
||||
|
||||
for(int i=0;i<altnaray.size();i++)
|
||||
print_line(rtos(altnaray[i].dot(final_normal_array[i])));
|
||||
*/
|
||||
|
||||
} else if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
|
||||
//generate normals (even if unused later)
|
||||
|
||||
_generate_normals(index_array, final_vertex_array, final_normal_array);
|
||||
if (OS::get_singleton()->is_stdout_verbose())
|
||||
print_line("Collada: Triangle mesh lacks normals, so normals were generated.");
|
||||
final_format |= Mesh::ARRAY_FORMAT_NORMAL;
|
||||
}
|
||||
|
||||
if (final_normal_array.size() && uv_src && binormal_src && tangent_src && !force_make_tangents) {
|
||||
|
||||
PoolVector<real_t> tarray;
|
||||
tarray.resize(vertex_array.size() * 4);
|
||||
PoolVector<real_t>::Write tarrayw = tarray.write();
|
||||
|
||||
for (int k = 0; k < vlen; k++) {
|
||||
tarrayw[k * 4 + 0] = vertex_array[k].tangent.normal.x;
|
||||
tarrayw[k * 4 + 1] = vertex_array[k].tangent.normal.y;
|
||||
tarrayw[k * 4 + 2] = vertex_array[k].tangent.normal.z;
|
||||
tarrayw[k * 4 + 3] = vertex_array[k].tangent.d;
|
||||
}
|
||||
|
||||
tarrayw = PoolVector<real_t>::Write();
|
||||
|
||||
final_tangent_array = tarray;
|
||||
} else if (final_normal_array.size() && primitive == Mesh::PRIMITIVE_TRIANGLES && final_uv_array.size() && (force_make_tangents || (material.is_valid()))) {
|
||||
//if this uses triangles, there are uvs and the material is using a normalmap, generate tangents and binormals, because they WILL be needed
|
||||
//generate binormals/tangents
|
||||
_generate_tangents_and_binormals(index_array, final_vertex_array, final_uv_array, final_normal_array, final_tangent_array);
|
||||
final_format |= Mesh::ARRAY_FORMAT_TANGENT;
|
||||
if (OS::get_singleton()->is_stdout_verbose())
|
||||
print_line("Collada: Triangle mesh lacks tangents (And normalmap was used), so tangents were generated.");
|
||||
}
|
||||
|
||||
if (color_src) {
|
||||
PoolVector<Color> colorarray;
|
||||
colorarray.resize(vertex_array.size());
|
||||
PoolVector<Color>::Write colorarrayw = colorarray.write();
|
||||
|
||||
for (int k = 0; k < vlen; k++) {
|
||||
colorarrayw[k] = vertex_array[k].color;
|
||||
}
|
||||
|
||||
colorarrayw = PoolVector<Color>::Write();
|
||||
|
||||
final_color_array = colorarray;
|
||||
}
|
||||
|
||||
if (has_weights) {
|
||||
PoolVector<float> weightarray;
|
||||
PoolVector<int> bonearray;
|
||||
|
||||
weightarray.resize(vertex_array.size() * 4);
|
||||
PoolVector<float>::Write weightarrayw = weightarray.write();
|
||||
bonearray.resize(vertex_array.size() * 4);
|
||||
PoolVector<int>::Write bonearrayw = bonearray.write();
|
||||
|
||||
for (int k = 0; k < vlen; k++) {
|
||||
float sum = 0;
|
||||
|
||||
if (has_weights) {
|
||||
Vector<float> weights;
|
||||
Vector<int> bones;
|
||||
weights.resize(VS::ARRAY_WEIGHTS_SIZE);
|
||||
bones.resize(VS::ARRAY_WEIGHTS_SIZE);
|
||||
//float sum=0.0;
|
||||
for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
|
||||
if (l < vertex_array[k].weights.size()) {
|
||||
weightarrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = vertex_array[k].weights[l].weight;
|
||||
sum += weightarrayw[k * VS::ARRAY_WEIGHTS_SIZE + l];
|
||||
bonearrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = int(vertex_array[k].weights[l].bone_idx);
|
||||
//COLLADA_PRINT(itos(k)+": "+rtos(bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l])+":"+rtos(weightarray[k*VS::ARRAY_WEIGHTS_SIZE+l]));
|
||||
weights[l] = vertex_array[k].weights[l].weight;
|
||||
bones[l] = vertex_array[k].weights[l].bone_idx;
|
||||
//sum += vertex_array[k].weights[l].weight;
|
||||
} else {
|
||||
|
||||
weightarrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = 0;
|
||||
bonearrayw[k * VS::ARRAY_WEIGHTS_SIZE + l] = 0;
|
||||
weights[l] = 0;
|
||||
bones[l] = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (sum<0.8)
|
||||
COLLADA_PRINT("ERROR SUMMING INDEX "+itos(k)+" had weights: "+itos(vertex_array[k].weights.size()));
|
||||
*/
|
||||
|
||||
surftool->add_bones(bones);
|
||||
surftool->add_weights(weights);
|
||||
}
|
||||
|
||||
weightarrayw = PoolVector<float>::Write();
|
||||
bonearrayw = PoolVector<int>::Write();
|
||||
surftool->add_vertex(vertex_array[k].vertex);
|
||||
}
|
||||
|
||||
final_weight_array = weightarray;
|
||||
final_bone_array = bonearray;
|
||||
for (List<int>::Element *E = indices_list.front(); E; E = E->next()) {
|
||||
surftool->add_index(E->get());
|
||||
}
|
||||
|
||||
if (!normal_src) {
|
||||
//should always be normals
|
||||
surftool->generate_normals();
|
||||
}
|
||||
|
||||
if ((!binormal_src || !tangent_src) && normal_src && uv_src && force_make_tangents) {
|
||||
|
||||
surftool->generate_tangents();
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// FINALLY CREATE SUFRACE //
|
||||
////////////////////////////
|
||||
|
||||
Array d;
|
||||
Array d = surftool->commit_to_arrays();
|
||||
d.resize(VS::ARRAY_MAX);
|
||||
|
||||
d[Mesh::ARRAY_INDEX] = index_array;
|
||||
d[Mesh::ARRAY_VERTEX] = final_vertex_array;
|
||||
|
||||
if (final_normal_array.size())
|
||||
d[Mesh::ARRAY_NORMAL] = final_normal_array;
|
||||
if (final_tangent_array.size())
|
||||
d[Mesh::ARRAY_TANGENT] = final_tangent_array;
|
||||
if (final_uv_array.size())
|
||||
d[Mesh::ARRAY_TEX_UV] = final_uv_array;
|
||||
if (final_uv2_array.size())
|
||||
d[Mesh::ARRAY_TEX_UV2] = final_uv2_array;
|
||||
if (final_color_array.size())
|
||||
d[Mesh::ARRAY_COLOR] = final_color_array;
|
||||
if (final_weight_array.size())
|
||||
d[Mesh::ARRAY_WEIGHTS] = final_weight_array;
|
||||
if (final_bone_array.size())
|
||||
d[Mesh::ARRAY_BONES] = final_bone_array;
|
||||
|
||||
Array mr;
|
||||
|
||||
////////////////////////////
|
||||
|
@ -1249,10 +1095,10 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
Array a = p_morph_meshes[mi]->surface_get_arrays(surface);
|
||||
//add valid weight and bone arrays if they exist, TODO check if they are unique to shape (generally not)
|
||||
|
||||
if (final_weight_array.size())
|
||||
a[Mesh::ARRAY_WEIGHTS] = final_weight_array;
|
||||
if (final_bone_array.size())
|
||||
a[Mesh::ARRAY_BONES] = final_bone_array;
|
||||
if (has_weights) {
|
||||
a[Mesh::ARRAY_WEIGHTS] = d[Mesh::ARRAY_WEIGHTS];
|
||||
a[Mesh::ARRAY_BONES] = d[Mesh::ARRAY_BONES];
|
||||
}
|
||||
|
||||
a[Mesh::ARRAY_INDEX] = Variant();
|
||||
//a.resize(Mesh::ARRAY_MAX); //no need for index
|
||||
|
|
|
@ -155,7 +155,7 @@ void GridMap::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"));
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "Cell", PROPERTY_HINT_NONE, "cell_", PROPERTY_USAGE_GROUP));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.01,16384,0.01"));
|
||||
p_list->push_back(PropertyInfo(Variant::VECTOR3, "cell_size"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_x"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_y"));
|
||||
|
@ -184,6 +184,7 @@ Ref<MeshLibrary> GridMap::get_theme() const {
|
|||
|
||||
void GridMap::set_cell_size(const Vector3 &p_size) {
|
||||
|
||||
ERR_FAIL_COND(p_size.x < 0.001 || p_size.y < 0.001 || p_size.z < 0.001);
|
||||
cell_size = p_size;
|
||||
_recreate_octant_data();
|
||||
}
|
||||
|
|
|
@ -691,6 +691,17 @@ void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvT
|
|||
fvTexcOut[1] = v.y;
|
||||
//fvTexcOut[1]=1.0-v.y;
|
||||
}
|
||||
|
||||
void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
|
||||
const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
|
||||
|
||||
Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
|
||||
Vertex *vtx = &varr[iFace * 3 + iVert]->get();
|
||||
|
||||
vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
|
||||
vtx->binormal = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]);
|
||||
}
|
||||
|
||||
void SurfaceTool::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) {
|
||||
|
||||
Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
|
||||
|
@ -715,8 +726,8 @@ void SurfaceTool::generate_tangents() {
|
|||
mkif.m_getNumVerticesOfFace = mikktGetNumVerticesOfFace;
|
||||
mkif.m_getPosition = mikktGetPosition;
|
||||
mkif.m_getTexCoord = mikktGetTexCoord;
|
||||
mkif.m_setTSpaceBasic = mikktSetTSpaceBasic;
|
||||
mkif.m_setTSpace = NULL;
|
||||
mkif.m_setTSpace = mikktSetTSpaceDefault;
|
||||
mkif.m_setTSpaceBasic = NULL;
|
||||
|
||||
SMikkTSpaceContext msc;
|
||||
msc.m_pInterface = &mkif;
|
||||
|
|
|
@ -90,6 +90,8 @@ private:
|
|||
static void mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert);
|
||||
static void mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert);
|
||||
static void mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
|
||||
static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
|
||||
const tbool bIsOrientationPreserving, const int iFace, const int iVert);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
|
Loading…
Reference in a new issue