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 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/modifier.c139
-rw-r--r--source/blender/blenlib/BLI_uvproject.h1
-rw-r--r--source/blender/blenlib/intern/uvproject.c19
3 files changed, 102 insertions, 57 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index b10456c53e0..8739a9c8b48 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -42,6 +42,7 @@
#include "BLI_kdtree.h"
#include "BLI_rand.h"
+#include "BLI_uvproject.h"
#include "MEM_guardedalloc.h"
@@ -3673,6 +3674,7 @@ typedef struct Projector {
Object *ob; /* object this projector is derived from */
float projmat[4][4]; /* projection matrix */
float normal[3]; /* projector normal in world space */
+ void *uci; /* optional uv-project info (panorama projection) */
} Projector;
static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
@@ -3688,9 +3690,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
int num_projectors = 0;
float aspect;
char uvname[32];
+ float aspx= umd->aspectx ? 1.0f : umd->aspectx;
+ float aspy= umd->aspecty ? 1.0f : umd->aspecty;
+ int free_uci= 0;
- if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
- else aspect = 1.0f;
+ aspect = aspx / aspy;
for(i = 0; i < umd->num_projectors; ++i)
if(umd->projectors[i])
@@ -3705,20 +3709,6 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
/* make sure we're using an existing layer */
validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
- /* make sure we are not modifying the original UV layer */
- tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
- CD_MTFACE, uvname);
-
- numVerts = dm->getNumVerts(dm);
-
- coords = MEM_callocN(sizeof(*coords) * numVerts,
- "uvprojectModifier_do coords");
- dm->getVertCos(dm, coords);
-
- /* convert coords to world space */
- for(i = 0, co = coords; i < numVerts; ++i, ++co)
- mul_m4_v3(ob->obmat, *co);
-
/* calculate a projection matrix and normal for each projector */
for(i = 0; i < num_projectors; ++i) {
float tmpmat[4][4];
@@ -3729,7 +3719,13 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
if(projectors[i].ob->type == OB_CAMERA) {
cam = (Camera *)projectors[i].ob->data;
- if(cam->type == CAM_PERSP) {
+ projectors[i].uci= NULL;
+
+ if(cam->flag & CAM_PANORAMA) {
+ projectors[i].uci= project_camera_info(projectors[i].ob, NULL, aspx, aspy);
+ free_uci= 1;
+ }
+ else if(cam->type == CAM_PERSP) {
float perspmat[4][4];
float xmax;
float xmin;
@@ -3778,15 +3774,15 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
offsetmat[3][0] = offsetmat[3][1] = offsetmat[3][2] = 0.5;
if (cam) {
- if (umd->aspectx == umd->aspecty) {
+ if (aspx == aspy) {
offsetmat[3][0] -= cam->shiftx;
offsetmat[3][1] -= cam->shifty;
- } else if (umd->aspectx < umd->aspecty) {
- offsetmat[3][0] -=(cam->shiftx * umd->aspecty/umd->aspectx);
+ } else if (aspx < aspy) {
+ offsetmat[3][0] -=(cam->shiftx * aspy/aspx);
offsetmat[3][1] -= cam->shifty;
} else {
offsetmat[3][0] -= cam->shiftx;
- offsetmat[3][1] -=(cam->shifty * umd->aspectx/umd->aspecty);
+ offsetmat[3][1] -=(cam->shifty * aspx/aspy);
}
}
@@ -3799,8 +3795,23 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
}
+ /* make sure we are not modifying the original UV layer */
+ tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
+ CD_MTFACE, uvname);
+
+
+ numVerts = dm->getNumVerts(dm);
+
+ coords = MEM_callocN(sizeof(*coords) * numVerts,
+ "uvprojectModifier_do coords");
+ dm->getVertCos(dm, coords);
+
+ /* convert coords to world space */
+ for(i = 0, co = coords; i < numVerts; ++i, ++co)
+ mul_m4_v3(ob->obmat, *co);
+
/* if only one projector, project coords to UVs */
- if(num_projectors == 1)
+ if(num_projectors == 1 && projectors[0].uci==NULL)
for(i = 0, co = coords; i < numVerts; ++i, ++co)
mul_project_m4_v4(projectors[0].projmat, *co);
@@ -3810,17 +3821,26 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
/* apply coords as UVs, and apply image if tfaces are new */
for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) {
if(override_image || !image || tface->tpage == image) {
- if(num_projectors == 1) {
- /* apply transformed coords as UVs */
- tface->uv[0][0] = coords[mf->v1][0];
- tface->uv[0][1] = coords[mf->v1][1];
- tface->uv[1][0] = coords[mf->v2][0];
- tface->uv[1][1] = coords[mf->v2][1];
- tface->uv[2][0] = coords[mf->v3][0];
- tface->uv[2][1] = coords[mf->v3][1];
- if(mf->v4) {
- tface->uv[3][0] = coords[mf->v4][0];
- tface->uv[3][1] = coords[mf->v4][1];
+ if(num_projectors == 1) {
+ if(projectors[0].uci) {
+ project_from_camera(tface->uv[0], coords[mf->v1], projectors[0].uci);
+ project_from_camera(tface->uv[1], coords[mf->v2], projectors[0].uci);
+ project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci);
+ if(mf->v3)
+ project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci);
+ }
+ else {
+ /* apply transformed coords as UVs */
+ tface->uv[0][0] = coords[mf->v1][0];
+ tface->uv[0][1] = coords[mf->v1][1];
+ tface->uv[1][0] = coords[mf->v2][0];
+ tface->uv[1][1] = coords[mf->v2][1];
+ tface->uv[2][0] = coords[mf->v3][0];
+ tface->uv[2][1] = coords[mf->v3][1];
+ if(mf->v4) {
+ tface->uv[3][0] = coords[mf->v4][0];
+ tface->uv[3][1] = coords[mf->v4][1];
+ }
}
} else {
/* multiple projectors, select the closest to face normal
@@ -3858,23 +3878,32 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
best_projector = &projectors[j];
}
}
-
- mul_project_m4_v4(best_projector->projmat, co1);
- mul_project_m4_v4(best_projector->projmat, co2);
- mul_project_m4_v4(best_projector->projmat, co3);
- if(mf->v4)
- mul_project_m4_v4(best_projector->projmat, co4);
-
- /* apply transformed coords as UVs */
- tface->uv[0][0] = co1[0];
- tface->uv[0][1] = co1[1];
- tface->uv[1][0] = co2[0];
- tface->uv[1][1] = co2[1];
- tface->uv[2][0] = co3[0];
- tface->uv[2][1] = co3[1];
- if(mf->v4) {
- tface->uv[3][0] = co4[0];
- tface->uv[3][1] = co4[1];
+
+ if(best_projector->uci) {
+ project_from_camera(tface->uv[0], coords[mf->v1], best_projector->uci);
+ project_from_camera(tface->uv[1], coords[mf->v2], best_projector->uci);
+ project_from_camera(tface->uv[2], coords[mf->v3], best_projector->uci);
+ if(mf->v3)
+ project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci);
+ }
+ else {
+ mul_project_m4_v4(best_projector->projmat, co1);
+ mul_project_m4_v4(best_projector->projmat, co2);
+ mul_project_m4_v4(best_projector->projmat, co3);
+ if(mf->v4)
+ mul_project_m4_v4(best_projector->projmat, co4);
+
+ /* apply transformed coords as UVs */
+ tface->uv[0][0] = co1[0];
+ tface->uv[0][1] = co1[1];
+ tface->uv[1][0] = co2[0];
+ tface->uv[1][1] = co2[1];
+ tface->uv[2][0] = co3[0];
+ tface->uv[2][1] = co3[1];
+ if(mf->v4) {
+ tface->uv[3][0] = co4[0];
+ tface->uv[3][1] = co4[1];
+ }
}
}
}
@@ -3886,7 +3915,15 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
MEM_freeN(coords);
-
+
+ if(free_uci) {
+ int j;
+ for(j = 0; j < num_projectors; ++j) {
+ if(projectors[j].uci) {
+ MEM_freeN(projectors[j].uci);
+ }
+ }
+ }
return dm;
}
diff --git a/source/blender/blenlib/BLI_uvproject.h b/source/blender/blenlib/BLI_uvproject.h
index 8e9a85136bb..a77ca60fc15 100644
--- a/source/blender/blenlib/BLI_uvproject.h
+++ b/source/blender/blenlib/BLI_uvproject.h
@@ -23,6 +23,7 @@
#define BKE_UVPROJECT_H
struct UvCameraInfo;
+struct Object;
/* create uv info from the camera, needs to be freed */
struct UvCameraInfo *project_camera_info(struct Object *ob, float rotmat[4][4], float winx, float winy);
diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c
index d6ba2d7da94..273cb01ce1c 100644
--- a/source/blender/blenlib/intern/uvproject.c
+++ b/source/blender/blenlib/intern/uvproject.c
@@ -36,7 +36,7 @@ typedef struct UvCameraInfo {
float shiftx, shifty;
float rotmat[4][4];
float caminv[4][4];
- short do_persp, do_pano;
+ short do_persp, do_pano, do_rotmat;
} UvCameraInfo;
void project_from_camera(float target[2], float source[3], UvCameraInfo *uci)
@@ -47,7 +47,8 @@ void project_from_camera(float target[2], float source[3], UvCameraInfo *uci)
pv4[3]= 1.0;
/* rotmat is the object matrix in this case */
- mul_m4_v4(uci->rotmat, pv4);
+ if(uci->do_rotmat)
+ mul_m4_v4(uci->rotmat, pv4);
/* caminv is the inverse camera matrix */
mul_m4_v4(uci->caminv, pv4);
@@ -87,7 +88,7 @@ void project_from_view(float target[2], float source[3], float persmat[4][4], fl
{
float pv[3], pv4[4], x= 0.0, y= 0.0;
- mul_m4_v3(rotmat, pv);
+ mul_v3_m4v3(pv, rotmat, source);
copy_v3_v3(pv4, source);
pv4[3]= 1.0;
@@ -123,7 +124,7 @@ void project_from_view(float target[2], float source[3], float persmat[4][4], fl
/* 'rotmat' can be obedit->obmat when uv project is used.
* 'winx' and 'winy' can be from scene->r.xsch/ysch */
-UvCameraInfo *project_camera_info(Object *ob, float rotmat[4][4], float winx, float winy)
+UvCameraInfo *project_camera_info(Object *ob, float (*rotmat)[4], float winx, float winy)
{
UvCameraInfo uci;
Camera *camera= ob->data;
@@ -138,7 +139,13 @@ UvCameraInfo *project_camera_info(Object *ob, float rotmat[4][4], float winx, fl
UvCameraInfo *uci_pt;
/* normal projection */
- copy_m4_m4(uci.rotmat, rotmat);
+ if(rotmat) {
+ copy_m4_m4(uci.rotmat, rotmat);
+ uci.do_rotmat= 1;
+ }
+ else {
+ uci.do_rotmat= 0;
+ }
/* also make aspect ratio adjustment factors */
if (winx > winy) {
@@ -166,7 +173,7 @@ void project_from_view_ortho(float target[2], float source[3], float rotmat[4][4
{
float pv[3];
- mul_m4_v3(rotmat, pv);
+ mul_v3_m4v3(pv, rotmat, source);
/* ortho projection */
target[0] = -pv[0];