synched with trunk at revision 36569
[blender.git] / source / blender / modifiers / intern / MOD_util.c
index c697daf..d008fcf 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/modifiers/intern/MOD_util.c
+ *  \ingroup modifiers
+ */
+
+
 #include <string.h>
 
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_curve_types.h"
+#include "DNA_meshdata_types.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+#include "BLI_math_matrix.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_mesh.h"
@@ -69,6 +77,92 @@ void get_texture_value(Tex *texture, float *tex_co, TexResult *texres)
                texres->tr = texres->tg = texres->tb = texres->tin;
 }
 
+void get_texture_coords(MappingInfoModifierData *dmd, Object *ob,
+                        DerivedMesh *dm,
+                        float (*co)[3], float (*texco)[3],
+                        int numVerts)
+{
+       int i;
+       int texmapping = dmd->texmapping;
+       float mapob_imat[4][4];
+
+       if(texmapping == MOD_DISP_MAP_OBJECT) {
+               if(dmd->map_object)
+                       invert_m4_m4(mapob_imat, dmd->map_object->obmat);
+               else /* if there is no map object, default to local */
+                       texmapping = MOD_DISP_MAP_LOCAL;
+       }
+
+       /* UVs need special handling, since they come from faces */
+       if(texmapping == MOD_DISP_MAP_UV) {
+               if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
+                       MFace *mface = dm->getFaceArray(dm);
+                       MFace *mf;
+                       char *done = MEM_callocN(sizeof(*done) * numVerts,
+                                                "get_texture_coords done");
+                       int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
+                       MTFace *tf;
+
+                       validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
+                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
+
+                       /* verts are given the UV from the first face that uses them */
+                       for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
+                               if(!done[mf->v1]) {
+                                       texco[mf->v1][0] = tf->uv[0][0];
+                                       texco[mf->v1][1] = tf->uv[0][1];
+                                       texco[mf->v1][2] = 0;
+                                       done[mf->v1] = 1;
+                               }
+                               if(!done[mf->v2]) {
+                                       texco[mf->v2][0] = tf->uv[1][0];
+                                       texco[mf->v2][1] = tf->uv[1][1];
+                                       texco[mf->v2][2] = 0;
+                                       done[mf->v2] = 1;
+                               }
+                               if(!done[mf->v3]) {
+                                       texco[mf->v3][0] = tf->uv[2][0];
+                                       texco[mf->v3][1] = tf->uv[2][1];
+                                       texco[mf->v3][2] = 0;
+                                       done[mf->v3] = 1;
+                               }
+                               if(!done[mf->v4]) {
+                                       texco[mf->v4][0] = tf->uv[3][0];
+                                       texco[mf->v4][1] = tf->uv[3][1];
+                                       texco[mf->v4][2] = 0;
+                                       done[mf->v4] = 1;
+                               }
+                       }
+
+                       /* remap UVs from [0, 1] to [-1, 1] */
+                       for(i = 0; i < numVerts; ++i) {
+                               texco[i][0] = texco[i][0] * 2 - 1;
+                               texco[i][1] = texco[i][1] * 2 - 1;
+                       }
+
+                       MEM_freeN(done);
+                       return;
+               } else /* if there are no UVs, default to local */
+                       texmapping = MOD_DISP_MAP_LOCAL;
+       }
+
+       for(i = 0; i < numVerts; ++i, ++co, ++texco) {
+               switch(texmapping) {
+               case MOD_DISP_MAP_LOCAL:
+                       copy_v3_v3(*texco, *co);
+                       break;
+               case MOD_DISP_MAP_GLOBAL:
+                       mul_v3_m4v3(*texco, ob->obmat, *co);
+                       break;
+               case MOD_DISP_MAP_OBJECT:
+                       mul_v3_m4v3(*texco, ob->obmat, *co);
+                       mul_m4_v3(mapob_imat, *texco);
+                       break;
+               }
+       }
+}
+
 void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
 {
        while((md=md->next) && md->type==eModifierType_Armature) {
@@ -148,7 +242,6 @@ DerivedMesh *get_dm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*ve
 /* only called by BKE_modifier.h/modifier.c */
 void modifier_type_init(ModifierTypeInfo *types[])
 {
-       memset(types, 0, sizeof(types));
 #define INIT_TYPE(typeName) (types[eModifierType_##typeName] = &modifierType_##typeName)
        INIT_TYPE(None);
        INIT_TYPE(Curve);
@@ -185,6 +278,7 @@ void modifier_type_init(ModifierTypeInfo *types[])
        INIT_TYPE(ShapeKey);
        INIT_TYPE(Solidify);
        INIT_TYPE(Screw);
+       INIT_TYPE(Warp);
        INIT_TYPE(NavMesh);
 #undef INIT_TYPE
 }