Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender/blender_mesh.cpp')
-rw-r--r--intern/cycles/blender/blender_mesh.cpp193
1 files changed, 126 insertions, 67 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 7055cf981c7..b1b1a638219 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -29,32 +29,138 @@
#include "util_foreach.h"
+#include "mikktspace.h"
+
CCL_NAMESPACE_BEGIN
-/* Find/Add */
+/* Tangent Space */
-static float3 tangent_from_triangle(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2)
-{
- float3 duv1 = tx2 - tx0;
- float3 duv2 = tx2 - tx1;
- float3 dp1 = v2 - v0;
- float3 dp2 = v2 - v1;
- float det = duv1[0] * duv2[1] - duv1[1] * duv2[0];
-
- if(det != 0.0f) {
- return normalize(dp1 * duv2[1] - dp2 * duv1[1]);
+struct MikkUserData {
+ MikkUserData(const BL::Mesh mesh_, const BL::MeshTextureFaceLayer layer_, int num_faces_)
+ : mesh(mesh_), layer(layer_), num_faces(num_faces_)
+ {
+ tangent.resize(num_faces*4);
}
- else {
- /* give back a sane default, using a valid edge as a fallback */
- float3 edge = v1 - v0;
- if(len(edge) == 0.0f)
- edge = v2 - v0;
+ BL::Mesh mesh;
+ BL::MeshTextureFaceLayer layer;
+ int num_faces;
+ vector<float4> tangent;
+};
+
+static int mikk_get_num_faces(const SMikkTSpaceContext *context)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ return userdata->num_faces;
+}
+
+static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
+ int4 vi = get_int4(f.vertices_raw());
+
+ return (vi[3] == 0)? 3: 4;
+}
- return normalize(edge);
+static void mikk_get_position(const SMikkTSpaceContext *context, float P[3], const int face_num, const int vert_num)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
+ int4 vi = get_int4(f.vertices_raw());
+ BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
+ float3 vP = get_float3(v.co());
+
+ P[0] = vP.x;
+ P[1] = vP.y;
+ P[2] = vP.z;
+}
+
+static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float uv[2], const int face_num, const int vert_num)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTextureFace tf = userdata->layer.data[face_num];
+ float3 tfuv;
+
+ if(vert_num == 0)
+ tfuv = get_float3(tf.uv1());
+ else if(vert_num == 1)
+ tfuv = get_float3(tf.uv2());
+ else if(vert_num == 2)
+ tfuv = get_float3(tf.uv3());
+ else
+ tfuv = get_float3(tf.uv4());
+
+ uv[0] = tfuv.x;
+ uv[1] = tfuv.y;
+}
+
+static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const int face_num, const int vert_num)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
+ int4 vi = get_int4(f.vertices_raw());
+ BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
+ float3 vN = get_float3(v.normal());
+
+ N[0] = vN.x;
+ N[1] = vN.y;
+ N[2] = vN.z;
+}
+
+static void mikk_set_tangent_space(const SMikkTSpaceContext *context, const float T[], const float sign, const int face, const int vert)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+
+ userdata->tangent[face*4 + vert] = make_float4(T[0], T[1], T[2], sign);
+}
+
+static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_layer, Mesh *mesh, vector<int>& nverts)
+{
+ /* setup userdata */
+ MikkUserData userdata(b_mesh, b_layer, nverts.size());
+
+ /* setup interface */
+ SMikkTSpaceInterface interface;
+ memset(&interface, 0, sizeof(interface));
+ interface.m_getNumFaces = mikk_get_num_faces;
+ interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
+ interface.m_getPosition = mikk_get_position;
+ interface.m_getTexCoord = mikk_get_texture_coordinate;
+ interface.m_getNormal = mikk_get_normal;
+ interface.m_setTSpaceBasic = mikk_set_tangent_space;
+
+ /* setup context */
+ SMikkTSpaceContext context;
+ memset(&context, 0, sizeof(context));
+ context.m_pUserData = &userdata;
+ context.m_pInterface = &interface;
+
+ /* compute tangents */
+ genTangSpaceDefault(&context);
+
+ /* create attribute */
+ /* todo: create float4 attribute for sign */
+ Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent"));
+ float3 *tangent = attr->data_float3();
+
+ for (int i = 0; i < nverts.size(); i++) {
+ tangent[0] = float4_to_float3(userdata.tangent[i*4 + 0]);
+ tangent[1] = float4_to_float3(userdata.tangent[i*4 + 1]);
+ tangent[2] = float4_to_float3(userdata.tangent[i*4 + 2]);
+ tangent += 3;
+
+ if(nverts[i] == 4) {
+ tangent[0] = float4_to_float3(userdata.tangent[i*4 + 0]);
+ tangent[1] = float4_to_float3(userdata.tangent[i*4 + 2]);
+ tangent[2] = float4_to_float3(userdata.tangent[i*4 + 3]);
+ tangent += 3;
+ }
}
}
+/* Create Mesh */
+
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
{
/* create vertices */
@@ -167,54 +273,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
if(!l->active_render())
continue;
- Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent"));
-
- /* compute average tangents per vertex */
- float3 *tangents = attr->data_float3();
- memset(tangents, 0, sizeof(float3)*mesh->verts.size());
-
- BL::MeshTextureFaceLayer::data_iterator t;
-
- size_t fi = 0; /* face index */
- b_mesh.tessfaces.begin(f);
- for(l->data.begin(t); t != l->data.end() && f != b_mesh.tessfaces.end(); ++t, ++fi, ++f) {
- int4 vi = get_int4(f->vertices_raw());
-
- float3 tx0 = get_float3(t->uv1());
- float3 tx1 = get_float3(t->uv2());
- float3 tx2 = get_float3(t->uv3());
-
- float3 v0 = mesh->verts[vi[0]];
- float3 v1 = mesh->verts[vi[1]];
- float3 v2 = mesh->verts[vi[2]];
-
- /* calculate tangent for the triangle;
- * get vertex positions, and find change in position with respect
- * to the texture coords in the first texture coord dimension */
- float3 tangent0 = tangent_from_triangle(v0, v1, v2, tx0, tx1, tx2);
-
- if(nverts[fi] == 4) {
- /* quad tangent */
- float3 tx3 = get_float3(t->uv4());
- float3 v3 = mesh->verts[vi[3]];
- float3 tangent1 = tangent_from_triangle(v0, v2, v3, tx0, tx2, tx3);
-
- tangents[vi[0]] += 0.5f*(tangent0 + tangent1);
- tangents[vi[1]] += tangent0;
- tangents[vi[2]] += 0.5f*(tangent0 + tangent1);
- tangents[vi[3]] += tangent1;
- }
- else {
- /* triangle tangent */
- tangents[vi[0]] += tangent0;
- tangents[vi[1]] += tangent0;
- tangents[vi[2]] += tangent0;
- }
- }
-
- /* normalize tangent vectors */
- for(int i = 0; i < mesh->verts.size(); i++)
- tangents[i] = normalize(tangents[i]);
+ mikk_compute_tangents(b_mesh, *l, mesh, nverts);
}
}
@@ -351,7 +410,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
create_mesh(scene, mesh, b_mesh, used_shaders);
/* free derived mesh */
- object_remove_mesh(b_data, b_mesh);
+ b_data.meshes.remove(b_mesh);
}
/* displacement method */
@@ -409,7 +468,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
mesh->attributes.remove(std);
/* free derived mesh */
- object_remove_mesh(b_data, b_mesh);
+ b_data.meshes.remove(b_mesh);
}
}