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:
-rw-r--r--source/blender/blenkernel/intern/modifier.c112
-rw-r--r--source/blender/blenlib/BLI_arithb.h5
-rw-r--r--source/blender/blenlib/intern/arithb.c12
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/src/buttons_editing.c11
5 files changed, 108 insertions, 33 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index d87d8b528d9..92a4df5ca27 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -2477,6 +2477,7 @@ static void uvprojectModifier_initData(ModifierData *md)
umd->image = NULL;
umd->flags = MOD_UVPROJECT_ADDUVS;
umd->num_projectors = 1;
+ umd->aspectx = umd->aspecty = 1.0f;
}
static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
@@ -2490,6 +2491,8 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
tumd->image = umd->image;
tumd->flags = umd->flags;
tumd->num_projectors = umd->num_projectors;
+ tumd->aspectx = umd->aspectx;
+ tumd->aspecty = umd->aspecty;
}
static void uvprojectModifier_foreachObjectLink(ModifierData *md, Object *ob,
@@ -2531,7 +2534,7 @@ static void uvprojectModifier_updateDepgraph(ModifierData *md,
typedef struct Projector {
Object *ob; /* object this projector is derived from */
- float imat[4][4]; /* world space -> projector space matrix */
+ float projmat[4][4]; /* projection matrix */
float normal[3]; /* projector normal in world space */
} Projector;
@@ -2546,6 +2549,10 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
int new_tfaces = 0;
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
int num_projectors = 0;
+ float aspect;
+
+ if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
+ else aspect = 1.0f;
for(i = 0; i < umd->num_projectors; ++i)
if(umd->projectors[i])
@@ -2573,38 +2580,79 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
for(i = 0, co = coords; i < numVerts; ++i, ++co)
Mat4MulVecfl(ob->obmat, *co);
- if(num_projectors == 1) {
- float imat[4][4];
-
- /* get projector space matrix */
- Mat4Invert(imat, projectors[0].ob->obmat);
- if(projectors[0].ob->type == OB_CAMERA) {
- Camera *cam = (Camera *)projectors[0].ob->data;
- if(cam->type == CAM_ORTHO)
- Mat4MulFloat3(imat[0], 1 / cam->ortho_scale);
- }
+ /* calculate a projection matrix and normal for each projector */
+ for(i = 0; i < num_projectors; ++i) {
+ float tmpmat[4][4];
+ float offsetmat[4][4];
+
+ /* calculate projection matrix */
+ Mat4Invert(projectors[i].projmat, projectors[i].ob->obmat);
+
+ if(projectors[i].ob->type == OB_CAMERA) {
+ Camera *cam = (Camera *)projectors[i].ob->data;
+ if(cam->type == CAM_PERSP) {
+ float perspmat[4][4];
+ float xmax;
+ float xmin;
+ float ymax;
+ float ymin;
+ float pixsize = cam->clipsta * 32.0 / cam->lens;
+
+ if(aspect > 1.0f) {
+ xmax = 0.5f * pixsize;
+ ymax = xmax / aspect;
+ } else {
+ ymax = 0.5f * pixsize;
+ xmax = ymax * aspect;
+ }
+ xmin = -xmax;
+ ymin = -ymax;
+
+ i_window(xmin, xmax, ymin, ymax,
+ cam->clipsta, cam->clipend, perspmat);
+ Mat4MulMat4(tmpmat, projectors[i].projmat, perspmat);
+ } else if(cam->type == CAM_ORTHO) {
+ float orthomat[4][4];
+ float xmax;
+ float xmin;
+ float ymax;
+ float ymin;
+
+ if(aspect > 1.0f) {
+ xmax = 0.5f * cam->ortho_scale;
+ ymax = xmax / aspect;
+ } else {
+ ymax = 0.5f * cam->ortho_scale;
+ xmax = ymax * aspect;
+ }
+ xmin = -xmax;
+ ymin = -ymax;
- /* convert coords to projector space */
- for(i = 0, co = coords; i < numVerts; ++i, ++co)
- Mat4MulVecfl(imat, *co);
- } else {
- /* calculate a world space -> projector space matrix and normal
- * for each projector
- */
- for(i = 0; i < num_projectors; ++i) {
- Mat4Invert(projectors[i].imat, projectors[i].ob->obmat);
- if(projectors[i].ob->type == OB_CAMERA) {
- Camera *cam = (Camera *)projectors[i].ob->data;
- if(cam->type == CAM_ORTHO)
- Mat4MulFloat3(*projectors[i].imat, 1 / cam->ortho_scale);
+ i_ortho(xmin, xmax, ymin, ymax,
+ cam->clipsta, cam->clipend, orthomat);
+ Mat4MulMat4(tmpmat, projectors[i].projmat, orthomat);
}
- projectors[i].normal[0] = 0;
- projectors[i].normal[1] = 0;
- projectors[i].normal[2] = 1;
- Mat4Mul3Vecfl(projectors[i].ob->obmat, projectors[i].normal);
+ } else {
+ Mat4CpyMat4(tmpmat, projectors[i].projmat);
}
+
+ Mat4One(offsetmat);
+ Mat4MulFloat3(offsetmat[0], 0.5);
+ offsetmat[3][0] = offsetmat[3][1] = offsetmat[3][2] = 0.5;
+ Mat4MulMat4(projectors[i].projmat, tmpmat, offsetmat);
+
+ /* calculate worldspace projector normal (for best projector test) */
+ projectors[i].normal[0] = 0;
+ projectors[i].normal[1] = 0;
+ projectors[i].normal[2] = 1;
+ Mat4Mul3Vecfl(projectors[i].ob->obmat, projectors[i].normal);
}
+ /* if only one projector, project coords to UVs */
+ if(num_projectors == 1)
+ for(i = 0, co = coords; i < numVerts; ++i, ++co)
+ Mat4MulVec3Project(projectors[0].projmat, *co);
+
mface = dm->getFaceArray(dm);
numFaces = dm->getNumFaces(dm);
@@ -2660,11 +2708,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
}
- Mat4MulVecfl(best_projector->imat, co1);
- Mat4MulVecfl(best_projector->imat, co2);
- Mat4MulVecfl(best_projector->imat, co3);
+ Mat4MulVec3Project(best_projector->projmat, co1);
+ Mat4MulVec3Project(best_projector->projmat, co2);
+ Mat4MulVec3Project(best_projector->projmat, co3);
if(mf->v4)
- Mat4MulVecfl(best_projector->imat, co4);
+ Mat4MulVec3Project(best_projector->projmat, co4);
/* apply transformed coords as UVs */
tface->uv[0][0] = co1[0];
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index c478262d500..fa7c05cce7c 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -401,6 +401,11 @@ Mat3Clr(
Mat3One(
float m[][3]
);
+ void
+Mat4MulVec3Project(
+ float mat[][4],
+ float *vec
+);
void
Mat4MulVec(
float mat[][4],
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index fd91a4231f6..de06fd3365d 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -838,6 +838,18 @@ void Mat4Mul3Vecfl( float mat[][4], float *vec)
vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2];
}
+void Mat4MulVec3Project(float mat[][4], float *vec)
+{
+ float w;
+
+ w = vec[0]*mat[0][3] + vec[1]*mat[1][3] + vec[2]*mat[2][3] + mat[3][3];
+ Mat4MulVecfl(mat, vec);
+
+ vec[0] /= w;
+ vec[1] /= w;
+ vec[2] /= w;
+}
+
void Mat4MulVec4fl( float mat[][4], float *vec)
{
float x,y,z;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 50cffb89872..1665c0da983 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -206,6 +206,7 @@ typedef struct UVProjectModifierData {
struct Image *image; /* the image to project */
int flags;
int num_projectors;
+ float aspectx, aspecty;
} UVProjectModifierData;
#define MOD_UVPROJECT_MAXPROJECTORS 10
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index b5e7d2b539e..78771cac20c 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -1355,7 +1355,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
height = 124;
if(dmd->texmapping == MOD_DISP_MAP_OBJECT) height += 19;
} else if (md->type==eModifierType_UVProject) {
- height = 67 + ((UVProjectModifierData *)md)->num_projectors * 19;
+ height = 86 + ((UVProjectModifierData *)md)->num_projectors * 19;
} else if (md->type==eModifierType_Decimate) {
height = 48;
} else if (md->type==eModifierType_Wave) {
@@ -1509,6 +1509,15 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
lx, (cy-=19), buttonWidth, 19,
&umd->flags, 0, 0, 0, 0,
"Add UV coordinates if missing");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspX:",
+ lx, (cy -= 19), buttonWidth / 2, 19, &umd->aspectx,
+ 1, 1000, 100, 2,
+ "Horizontal Aspect Ratio");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspY:",
+ lx + (buttonWidth / 2) + 1, cy, buttonWidth / 2, 19,
+ &umd->aspecty,
+ 1, 1000, 100, 2,
+ "Vertical Aspect Ratio");
uiDefButI(block, NUM, B_MODIFIER_RECALC, "Projectors:",
lx, (cy -= 19), buttonWidth, 19, &umd->num_projectors,
1, MOD_UVPROJECT_MAXPROJECTORS, 0, 0,