diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-10-14 01:01:25 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-10-14 01:01:25 -0300 |
commit | a84ba9c853f972f8e666b17f3e0f875b7282e6c1 (patch) | |
tree | 70a5d44acbecc93011333d13dd51b1786d42eae3 /scene/resources | |
parent | 13a848e332092b40956739a08fa0dac3357db950 (diff) | |
download | redot-engine-a84ba9c853f972f8e666b17f3e0f875b7282e6c1.tar.gz |
Collada
-=-=-=-
-Fixed some DAE import & export bugs
-Changed Collada exporter to use the mesh loops API
-Added tangent export to Collada exporter
-Added triangulation option to Collada exporter
-Changed a little how normalmaps are handled in shader. Not sure if it's working properly, be careful.
-Fixed some strange bug with kinematic bodies #776
-Fix release compilaiton issues #782
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/mesh.cpp | 27 | ||||
-rw-r--r-- | scene/resources/mesh.h | 1 | ||||
-rw-r--r-- | scene/resources/surface_tool.cpp | 206 | ||||
-rw-r--r-- | scene/resources/surface_tool.h | 10 |
4 files changed, 107 insertions, 137 deletions
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index c6e492fcb3..3aeccdc551 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -29,6 +29,7 @@ #include "mesh.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" +#include "surface_tool.h" static const char*_array_name[]={ "vertex_array", @@ -648,6 +649,30 @@ void Mesh::center_geometry() { } +void Mesh::regen_normalmaps() { + + + Vector< Ref<SurfaceTool> > surfs; + for(int i=0;i<get_surface_count();i++) { + + Ref<SurfaceTool> st = memnew( SurfaceTool ); + st->create_from(Ref<Mesh>(this),i); + surfs.push_back(st); + } + + while (get_surface_count()) { + surface_remove(0); + } + + for(int i=0;i<surfs.size();i++) { + + surfs[i]->generate_tangents(); + surfs[i]->commit(Ref<Mesh>(this)); + } +} + + + Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) @@ -740,6 +765,8 @@ void Mesh::_bind_methods() { ObjectTypeDB::bind_method(_MD("surface_get_name","surf_idx"),&Mesh::surface_get_name); ObjectTypeDB::bind_method(_MD("center_geometry"),&Mesh::center_geometry); ObjectTypeDB::set_method_flags(get_type_static(),_SCS("center_geometry"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + ObjectTypeDB::bind_method(_MD("regen_normalmaps"),&Mesh::regen_normalmaps); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("regen_normalmaps"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); ObjectTypeDB::bind_method(_MD("set_custom_aabb","aabb"),&Mesh::set_custom_aabb); ObjectTypeDB::bind_method(_MD("get_custom_aabb"),&Mesh::get_custom_aabb); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 5243163a4d..d6ab6a1198 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -167,6 +167,7 @@ public: Ref<Shape> create_convex_shape() const; void center_geometry(); + void regen_normalmaps(); DVector<Face3> get_faces() const; Ref<TriangleMesh> generate_triangle_mesh() const; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 2856101674..dd39205932 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -105,7 +105,7 @@ void SurfaceTool::add_vertex( const Vector3& p_vertex) { vtx.weights=last_weights; vtx.bones=last_bones; vtx.tangent=last_tangent.normal; - vtx.binormal=last_tangent.normal.cross(last_normal).normalized() * last_tangent.d; + vtx.binormal=last_normal.cross(last_tangent.normal).normalized() * last_tangent.d; vertex_array.push_back(vtx); first=false; format|=Mesh::ARRAY_FORMAT_VERTEX; @@ -299,7 +299,9 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) { w[idx+0]=v.tangent.x; w[idx+1]=v.tangent.y; w[idx+2]=v.tangent.z; - float d = v.binormal.dot(v.normal.cross(v.tangent)); + + //float d = v.tangent.dot(v.binormal,v.normal); + float d = v.binormal.dot( v.normal.cross(v.tangent)); w[idx+3]=d<0 ? -1 : 1; } @@ -565,6 +567,7 @@ void SurfaceTool::create_from(const Ref<Mesh>& p_existing, int p_surface) { clear(); primitive=p_existing->surface_get_primitive_type(p_surface); _create_list(p_existing,p_surface,&vertex_array,&index_array,format); + material=p_existing->surface_get_material(p_surface); } @@ -611,165 +614,96 @@ void SurfaceTool::append_from(const Ref<Mesh>& p_existing, int p_surface,const T } +//mikktspace callbacks +int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext * pContext) { -void SurfaceTool::generate_tangents() { - - ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_TEX_UV)); - ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_NORMAL)); - - - if (index_array.size()) { - - Vector<List<Vertex>::Element*> vtx; - vtx.resize(vertex_array.size()); - int idx=0; - for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) { - vtx[idx++]=E; - E->get().binormal=Vector3(); - E->get().tangent=Vector3(); - } - - for (List<int>::Element *E=index_array.front();E;) { - - int i[3]; - i[0]=E->get(); - E=E->next(); - ERR_FAIL_COND(!E); - i[1]=E->get(); - E=E->next(); - ERR_FAIL_COND(!E); - i[2]=E->get(); - E=E->next(); - ERR_FAIL_COND(!E); - - - Vector3 v1 = vtx[ i[0] ]->get().vertex; - Vector3 v2 = vtx[ i[1] ]->get().vertex; - Vector3 v3 = vtx[ i[2] ]->get().vertex; - - Vector2 w1 = vtx[ i[0] ]->get().uv; - Vector2 w2 = vtx[ i[1] ]->get().uv; - Vector2 w3 = vtx[ i[2] ]->get().uv; - - - float x1 = v2.x - v1.x; - float x2 = v3.x - v1.x; - float y1 = v2.y - v1.y; - float y2 = v3.y - v1.y; - float z1 = v2.z - v1.z; - float z2 = v3.z - v1.z; - - float s1 = w2.x - w1.x; - float s2 = w3.x - w1.x; - float t1 = w2.y - w1.y; - float t2 = w3.y - w1.y; - - float r = (s1 * t2 - s2 * t1); - - Vector3 binormal,tangent; - - if (r==0) { - binormal=Vector3(0,0,0); - tangent=Vector3(0,0,0); - } else { - tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); - binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); - } - - tangent.normalize(); - binormal.normalize(); - Vector3 normal=Plane( v1, v2, v3 ).normal; - - Vector3 tangentp = tangent - normal * normal.dot( tangent ); - Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal)); - - tangentp.normalize(); - binormalp.normalize(); + Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData); + return varr.size()/3; +} +int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext * pContext, const int iFace){ + return 3; //always 3 +} +void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert){ - for (int j=0;j<3;j++) { - vtx[ i[j] ]->get().binormal+=binormalp; - vtx[ i[j] ]->get().tangent+=tangentp; + Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData); + Vector3 v = varr[iFace*3+iVert]->get().vertex; + fvPosOut[0]=v.x; + fvPosOut[1]=v.y; + fvPosOut[2]=v.z; - } - } - for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) { - E->get().binormal.normalize(); - E->get().tangent.normalize(); - } +} +void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext * pContext, float fvNormOut[], const int iFace, const int iVert){ - } else { + Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData); + Vector3 v = varr[iFace*3+iVert]->get().normal; + fvNormOut[0]=v.x; + fvNormOut[1]=v.y; + fvNormOut[2]=v.z; - for (List<Vertex>::Element *E=vertex_array.front();E;) { +} +void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext * pContext, float fvTexcOut[], const int iFace, const int iVert){ - List< Vertex >::Element *v[3]; - v[0]=E; - v[1]=v[0]->next(); - ERR_FAIL_COND(!v[1]); - v[2]=v[1]->next(); - ERR_FAIL_COND(!v[2]); - E=v[2]->next(); + Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData); + Vector2 v = varr[iFace*3+iVert]->get().uv; + fvTexcOut[0]=v.x; + //fvTexcOut[1]=v.y; + fvTexcOut[1]=1.0-v.y; - Vector3 v1 = v[0]->get().vertex; - Vector3 v2 = v[1]->get().vertex; - Vector3 v3 = v[2]->get().vertex; +} +void SurfaceTool::mikktSetTSpaceBasic(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert){ - Vector2 w1 = v[0]->get().uv; - Vector2 w2 = v[1]->get().uv; - Vector2 w3 = v[2]->get().uv; + 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 = vtx.normal.cross(vtx.tangent) * fSign; +} - float x1 = v2.x - v1.x; - float x2 = v3.x - v1.x; - float y1 = v2.y - v1.y; - float y2 = v3.y - v1.y; - float z1 = v2.z - v1.z; - float z2 = v3.z - v1.z; - float s1 = w2.x - w1.x; - float s2 = w3.x - w1.x; - float t1 = w2.y - w1.y; - float t2 = w3.y - w1.y; +void SurfaceTool::generate_tangents() { - float r = (s1 * t2 - s2 * t1); + ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_TEX_UV)); + ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_NORMAL)); - Vector3 binormal,tangent; + bool indexed = index_array.size()>0; + if (indexed) + deindex(); - if (r==0) { - binormal=Vector3(0,0,0); - tangent=Vector3(0,0,0); - } else { - tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); - binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); - } - tangent.normalize(); - binormal.normalize(); - Vector3 normal=Plane( v1, v2, v3 ).normal; + SMikkTSpaceInterface mkif; + mkif.m_getNormal=mikktGetNormal; + mkif.m_getNumFaces=mikktGetNumFaces; + mkif.m_getNumVerticesOfFace=mikktGetNumVerticesOfFace; + mkif.m_getPosition=mikktGetPosition; + mkif.m_getTexCoord=mikktGetTexCoord; + mkif.m_setTSpaceBasic=mikktSetTSpaceBasic; + mkif.m_setTSpace=NULL; - Vector3 tangentp = tangent - normal * normal.dot( tangent ); - Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal)); + SMikkTSpaceContext msc; + msc.m_pInterface=&mkif; - tangentp.normalize(); - binormalp.normalize(); + Vector<List<Vertex>::Element*> vtx; + vtx.resize(vertex_array.size()); + int idx=0; + for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) { + vtx[idx++]=E; + E->get().binormal=Vector3(); + E->get().tangent=Vector3(); + } + msc.m_pUserData=&vtx; + bool res = genTangSpaceDefault(&msc); - for (int j=0;j<3;j++) { - v[j]->get().binormal=binormalp; - v[j]->get().tangent=tangentp; + ERR_FAIL_COND(!res); + format|=Mesh::ARRAY_FORMAT_TANGENT; - } - } - } + if (indexed) + index(); - format|=Mesh::ARRAY_FORMAT_TANGENT; } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index fe82d3a4ce..fc5940145b 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -30,7 +30,7 @@ #define SURFACE_TOOL_H #include "scene/resources/mesh.h" - +#include "mikktspace.h" class SurfaceTool : public Reference { @@ -82,6 +82,14 @@ private: void _create_list(const Ref<Mesh>& p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index,int &lformat); + + //mikktspace callbacks + static int mikktGetNumFaces(const SMikkTSpaceContext * pContext); + static int mikktGetNumVerticesOfFace(const SMikkTSpaceContext * pContext, const int iFace); + static void mikktGetPosition(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert); + 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); protected: static void _bind_methods(); |