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:
authorTon Roosendaal <ton@blender.org>2004-09-14 23:03:11 +0400
committerTon Roosendaal <ton@blender.org>2004-09-14 23:03:11 +0400
commit37f57288cbcdb54770a8b01d74a323d62251fe9e (patch)
tree6f0316050cbc80fb66408d3dfb43705c273fd2ef /source/blender/blenkernel/intern/lattice.c
parent807339b4a7a0be25fbdc3de32e2c264f3f0b1e5a (diff)
Lot of code... 2 new features:
1) Curve deform http://www.blender3d.org/cms/Curve_Deform.392.0.html Works simple as expected, but keep track of the rotation axis in F7 buttons (Track X Y Z) Only Mesh deform supported now. Code changes: - centralized deformation calls in curve_modifiers() mesh_modifiers() etcetera. Here also other effects can be added like wave. Now the evaluation order is fixed, but should become optional. It also doesnt use the Displist anymore as deform-input. That latter part is unfinished yet. This code also is used for Hooks and will be needed for softbody - made convention stricter that displists are being checked on in drawobject(), this to prevent routines to make new displists recursively (like armature does). Now a freedisplist() is sufficient to signal that a new displaylist should be made. 2) Object Hooks http://www.blender3d.org/cms/Object_Hooks.391.0.html Support for Hooks is added to Mesh, Lattice, Curve and Surface objects. For Armatures this would require some more work & research. Main goal for this feature is to provide quick & simple access to the underlying geometry in Objects on Object level, supporting hierarchies and Ipos etc.
Diffstat (limited to 'source/blender/blenkernel/intern/lattice.c')
-rw-r--r--source/blender/blenkernel/intern/lattice.c288
1 files changed, 176 insertions, 112 deletions
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 3cb2f20925f..959cb7001fb 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -53,23 +53,27 @@
#include "DNA_key_types.h"
#include "DNA_ika_types.h"
-#include "BKE_utildefines.h"
+#include "BKE_anim.h"
#include "BKE_armature.h"
-#include "BKE_library.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_screen.h"
+#include "BKE_curve.h"
+#include "BKE_deform.h"
#include "BKE_displist.h"
-#include "BKE_lattice.h"
+#include "BKE_global.h"
+#include "BKE_ika.h"
#include "BKE_key.h"
+#include "BKE_lattice.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_object.h"
-#include "BKE_ika.h"
-#include "BKE_curve.h"
+#include "BKE_screen.h"
+#include "BKE_utildefines.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include "blendef.h"
+
Lattice *editLatt=0, *deformLatt=0;
float *latticedata=0, latmat[4][4];
@@ -236,6 +240,7 @@ void init_latt_deform(Object *oblatt, Object *ob)
fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
+ lattice_modifier(oblatt, 's');
bp= deformLatt->def;
if(ob) where_is_object(ob);
@@ -279,6 +284,9 @@ void init_latt_deform(Object *oblatt, Object *ob)
}
vec[2]+= dw;
}
+
+ lattice_modifier(oblatt, 'e');
+
}
void calc_latt_deform(float *co)
@@ -383,6 +391,119 @@ void end_latt_deform()
latticedata= 0;
}
+ /* calculations is in local space of deformed object
+ so we store in latmat transform from path coord inside object
+ */
+typedef struct {
+ float dmin[3], dmax[3], dsize, dloc[3];
+ float curvespace[4][4], objectspace[4][4];
+} CurveDeform;
+
+static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd)
+{
+ Mat4Invert(ob->imat, ob->obmat);
+ Mat4MulMat4(cd->objectspace, par->obmat, ob->imat);
+ Mat4Invert(cd->curvespace, cd->objectspace);
+
+ // offset vector for 'no smear'
+ Mat4Invert(par->imat, par->obmat);
+ VecMat4MulVecfl(cd->dloc, par->imat, ob->obmat[3]);
+
+}
+
+/* this makes sure we can extend for non-cyclic */
+static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir) /* returns OK */
+{
+ Curve *cu= ob->data;
+ BevList *bl;
+ float ctime1;
+ int cycl=0;
+
+ /* test for cyclic */
+ bl= cu->bev.first;
+ if(bl && bl->poly> -1) cycl= 1;
+
+ if(cycl==0) {
+ ctime1= CLAMPIS(ctime, 0.0, 1.0);
+ }
+ else ctime1= ctime;
+
+ if(where_on_path(ob, ctime1, vec, dir)) {
+
+ if(cycl==0) {
+ Path *path= cu->path;
+ float dvec[3];
+
+ if(ctime < 0.0) {
+ VecSubf(dvec, path->data+4, path->data);
+ VecMulf(dvec, ctime*(float)path->len);
+ VECADD(vec, vec, dvec);
+ }
+ else if(ctime > 1.0) {
+ VecSubf(dvec, path->data+4*path->len-4, path->data+4*path->len-8);
+ VecMulf(dvec, (ctime-1.0)*(float)path->len);
+ VECADD(vec, vec, dvec);
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+ /* for each point, rotate & translate to curve */
+ /* use path, since it has constant distances */
+ /* co: local coord, result local too */
+static void calc_curve_deform(Object *par, float *co, short axis, CurveDeform *cd)
+{
+ Curve *cu= par->data;
+ float fac, loc[3], dir[3], *quat, mat[3][3], cent[3];
+ short upflag, index;
+
+ if(axis==OB_POSX || axis==OB_NEGX) {
+ upflag= OB_POSZ;
+ cent[0]= 0.0;
+ cent[1]= co[1];
+ cent[2]= co[2];
+ index= 0;
+ }
+ else if(axis==OB_POSY || axis==OB_NEGY) {
+ upflag= OB_POSZ;
+ cent[0]= co[0];
+ cent[1]= 0.0;
+ cent[2]= co[2];
+ index= 1;
+ }
+ else {
+ upflag= OB_POSY;
+ cent[0]= co[0];
+ cent[1]= co[1];
+ cent[2]= 0.0;
+ index= 2;
+ }
+ /* to be sure */
+ if(cu->path==NULL) calc_curvepath(par);
+
+ /* options */
+ if(cu->flag & CU_STRETCH)
+ fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
+ else
+ fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
+
+ if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
+
+ quat= vectoquat(dir, axis, upflag);
+ QuatToMat3(quat, mat);
+
+ /* local rotation */
+ Mat3MulVecfl(mat, cent);
+
+ /* translation */
+ VECADD(co, cent, loc);
+
+ }
+
+}
+
static int _object_deform(Object *ob, int applyflag)
{
@@ -391,32 +512,59 @@ static int _object_deform(Object *ob, int applyflag)
DispList *dl;
MVert *mvert;
float *fp;
- int a, tot;
+ int a, tot, flag;
- if(ob->parent==0) return 0;
+ if(ob->parent==NULL) return 0;
/* always try to do the entire deform in this function: apply! */
-
- if(ob->parent->type==OB_LATTICE) {
+
+ if(ob->parent->type==OB_CURVE) {
+ CurveDeform cd;
- init_latt_deform(ob->parent, ob);
+ if (ob->partype != PARSKEL){
+ return 0;
+ }
+ cu= ob->parent->data;
+ flag= cu->flag;
+ cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
if(ob->type==OB_MESH) {
+
me= ob->data;
+ if(me->totvert==0) return 0;
- dl= find_displist_create(&ob->disp, DL_VERTS);
+ /* init deform */
+ init_curve_deform(ob->parent, ob, &cd);
- mvert= me->mvert;
- if(dl->verts) MEM_freeN(dl->verts);
- dl->nr= me->totvert;
- dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
+ /* transformation to curve space, and min max*/
+ INIT_MINMAX(cd.dmin, cd.dmax);
+
+ for(a=0, mvert=me->mvert; a<me->totvert; a++, mvert++) {
+ Mat4MulVecfl(cd.curvespace, mvert->co);
+ DO_MINMAX(mvert->co, cd.dmin, cd.dmax);
+ }
- for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
- if(applyflag) calc_latt_deform(mvert->co);
- else {
- VECCOPY(fp, mvert->co);
- calc_latt_deform(fp);
- }
+ mvert= me->mvert;
+ for(a=0; a<me->totvert; a++, mvert++) {
+ calc_curve_deform(ob->parent, mvert->co, ob->trackflag, &cd);
+ /* move coord back to objectspace */
+ Mat4MulVecfl(cd.objectspace, mvert->co);
+ }
+ }
+ /* restore */
+ cu->flag = flag;
+ return 1;
+ }
+ else if(ob->parent->type==OB_LATTICE) {
+
+ init_latt_deform(ob->parent, ob);
+
+ if(ob->type==OB_MESH) {
+ me= ob->data;
+
+ mvert= me->mvert;
+ for(a=0; a<me->totvert; a++, mvert++) {
+ calc_latt_deform(mvert->co);
}
}
else if(ob->type==OB_MBALL) {
@@ -479,9 +627,6 @@ static int _object_deform(Object *ob, int applyflag)
}
}
end_latt_deform();
-
- boundbox_displist(ob);
-
return 1;
}
else if(ob->parent->type==OB_ARMATURE) {
@@ -495,97 +640,16 @@ static int _object_deform(Object *ob, int applyflag)
case OB_MESH:
me= ob->data;
- dl= find_displist_create(&ob->disp, DL_VERTS);
-
mvert= me->mvert;
- if(dl->verts) MEM_freeN(dl->verts);
- dl->nr= me->totvert;
- dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
-
- for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
- if(applyflag){
- calc_armature_deform(ob->parent, mvert->co, a);
- }
- else {
- VECCOPY(fp, mvert->co);
- calc_armature_deform(ob->parent, fp, a);
- }
+ for(a=0; a<me->totvert; a++, mvert++) {
+ calc_armature_deform(ob->parent, mvert->co, a);
}
-
break;
- default:
+ case OB_CURVE:
+ case OB_SURF:
break;
}
- boundbox_displist(ob);
- return 1;
- }
- else if(ob->parent->type==OB_IKA) {
-
- Ika *ika;
-
- if(ob->partype!=PARSKEL) return 0;
-
- ika= ob->parent->data;
- if(ika->def==0) return 0;
-
- init_skel_deform(ob->parent, ob);
-
- if(ob->type==OB_MESH) {
- me= ob->data;
-
- dl= find_displist_create(&ob->disp, DL_VERTS);
-
- mvert= me->mvert;
- if(dl->verts) MEM_freeN(dl->verts);
- dl->nr= me->totvert;
- dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
-
- for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
- if(applyflag) calc_skel_deform(ika, mvert->co);
- else {
- VECCOPY(fp, mvert->co);
- calc_skel_deform(ika, fp);
- }
- }
- }
- else if ELEM(ob->type, OB_CURVE, OB_SURF) {
-
- cu= ob->data;
- if(applyflag) {
- Nurb *nu;
- BPoint *bp;
-
- nu= cu->nurb.first;
- while(nu) {
- if(nu->bp) {
- a= nu->pntsu*nu->pntsv;
- bp= nu->bp;
- while(a--) {
- calc_skel_deform(ika, bp->vec);
- bp++;
- }
- }
- nu= nu->next;
- }
- }
-
- /* when apply, do this too, looks more interactive */
- dl= cu->disp.first;
- while(dl) {
-
- fp= dl->verts;
- tot= dl->nr*dl->parts;
- for(a=0; a<tot; a++, fp+=3) {
- calc_skel_deform(ika, fp);
- }
-
- dl= dl->next;
- }
- }
-
- boundbox_displist(ob);
-
return 1;
}