|
|
|
|
@ -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;
|
|
|
|
|
|
|
|
|
|
uint32_t final_format = 0;
|
|
|
|
|
|
|
|
|
|
//create format
|
|
|
|
|
final_format = Mesh::ARRAY_FORMAT_VERTEX | Mesh::ARRAY_FORMAT_INDEX;
|
|
|
|
|
Ref<SurfaceTool> surftool;
|
|
|
|
|
surftool.instance();
|
|
|
|
|
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
|
|
|
|
|
|
|
|
|
for (int k = 0; k < vertex_array.size(); k++) {
|
|
|
|
|
if (normal_src) {
|
|
|
|
|
final_format |= Mesh::ARRAY_FORMAT_NORMAL;
|
|
|
|
|
if (uv_src && binormal_src && tangent_src) {
|
|
|
|
|
final_format |= Mesh::ARRAY_FORMAT_TANGENT;
|
|
|
|
|
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;
|
|
|
|
|
if (uv_src) {
|
|
|
|
|
surftool->add_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//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 (uv2_src) {
|
|
|
|
|
surftool->add_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
surftool->add_color(vertex_array[k].color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
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()));
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
weightarrayw = PoolVector<float>::Write();
|
|
|
|
|
bonearrayw = PoolVector<int>::Write();
|
|
|
|
|
surftool->add_bones(bones);
|
|
|
|
|
surftool->add_weights(weights);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final_weight_array = weightarray;
|
|
|
|
|
final_bone_array = bonearray;
|
|
|
|
|
surftool->add_vertex(vertex_array[k].vertex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|