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:
authorJoseph Eagar <joeedh@gmail.com>2009-09-16 21:43:09 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-09-16 21:43:09 +0400
commitdeebf4f8f0d79169a0e6c2a391670419b6492bfe (patch)
tree2a0aaf4042aa78e9d1d835f4544e07c6123e67a9 /source/blender/blenkernel/intern
parent6b0679a3999d8e5abc60730f523879eadbedcd8f (diff)
merge with 2.5/trunk at r23271
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/action.c6
-rw-r--r--source/blender/blenkernel/intern/anim.c98
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c37
-rw-r--r--source/blender/blenkernel/intern/armature.c21
-rw-r--r--source/blender/blenkernel/intern/boids.c198
-rw-r--r--source/blender/blenkernel/intern/booleanops.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c2
-rw-r--r--source/blender/blenkernel/intern/cloth.c76
-rw-r--r--source/blender/blenkernel/intern/collision.c16
-rw-r--r--source/blender/blenkernel/intern/colortools.c4
-rw-r--r--source/blender/blenkernel/intern/constraint.c104
-rw-r--r--source/blender/blenkernel/intern/curve.c769
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c142
-rw-r--r--source/blender/blenkernel/intern/displist.c50
-rw-r--r--source/blender/blenkernel/intern/fcurve.c6
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c1
-rw-r--r--source/blender/blenkernel/intern/font.c9
-rw-r--r--source/blender/blenkernel/intern/gpencil.c7
-rw-r--r--source/blender/blenkernel/intern/group.c10
-rw-r--r--source/blender/blenkernel/intern/image.c5
-rw-r--r--source/blender/blenkernel/intern/implicit.c110
-rw-r--r--source/blender/blenkernel/intern/ipo.c2
-rw-r--r--source/blender/blenkernel/intern/key.c115
-rw-r--r--source/blender/blenkernel/intern/lattice.c31
-rw-r--r--source/blender/blenkernel/intern/library.c237
-rw-r--r--source/blender/blenkernel/intern/material.c57
-rw-r--r--source/blender/blenkernel/intern/mesh.c4
-rw-r--r--source/blender/blenkernel/intern/modifier.c82
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c151
-rw-r--r--source/blender/blenkernel/intern/multires.c6
-rw-r--r--source/blender/blenkernel/intern/nla.c2
-rw-r--r--source/blender/blenkernel/intern/node.c9
-rw-r--r--source/blender/blenkernel/intern/object.c72
-rw-r--r--source/blender/blenkernel/intern/packedFile.c10
-rw-r--r--source/blender/blenkernel/intern/particle.c755
-rw-r--r--source/blender/blenkernel/intern/particle_system.c717
-rw-r--r--source/blender/blenkernel/intern/pointcache.c202
-rw-r--r--source/blender/blenkernel/intern/sca.c26
-rw-r--r--source/blender/blenkernel/intern/scene.c20
-rw-r--r--source/blender/blenkernel/intern/screen.c21
-rw-r--r--source/blender/blenkernel/intern/sequence.c22
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c983
-rw-r--r--source/blender/blenkernel/intern/softbody.c321
-rw-r--r--source/blender/blenkernel/intern/sound.c97
-rw-r--r--source/blender/blenkernel/intern/text.c125
-rw-r--r--source/blender/blenkernel/intern/texture.c6
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c2
49 files changed, 3410 insertions, 2342 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d37a0329582..57af8ce9ae2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2311,7 +2311,7 @@ static void clear_mesh_caches(Object *ob)
static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
{
Object *obact = scene->basact?scene->basact->object:NULL;
- int editing = paint_facesel_test(ob)|(ob && ob->mode & OB_MODE_PARTICLE_EDIT);
+ int editing = paint_facesel_test(ob);
int needMapping = editing && (ob==obact);
float min[3], max[3];
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 47de044ea25..2bde61818bf 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -214,7 +214,7 @@ bAction *copy_action (bAction *src)
/* Get the active action-group for an Action */
-bActionGroup *get_active_actiongroup (bAction *act)
+static bActionGroup *get_active_actiongroup (bAction *act)
{
bActionGroup *agrp= NULL;
@@ -1165,7 +1165,7 @@ typedef struct NlaIpoChannel {
int type;
} NlaIpoChannel;
-void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime)
+static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime)
{
bActionChannel *achan= get_action_channel(act, name);
IpoCurve *icu;
@@ -1258,7 +1258,7 @@ static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int
}
}
-int execute_ipochannels(ListBase *lb)
+static int execute_ipochannels(ListBase *lb)
{
NlaIpoChannel *nic;
int count = 0;
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 7d9d261f306..63092379825 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -88,15 +88,16 @@ void free_path(Path *path)
void calc_curvepath(Object *ob)
{
BevList *bl;
- BevPoint *bevp, *bevpn, *bevpfirst, *bevplast, *tempbevp;
+ BevPoint *bevp, *bevpn, *bevpfirst, *bevplast;
+ PathPoint *pp;
Curve *cu;
Nurb *nu;
Path *path;
- float *fp, *dist, *maxdist, x, y, z;
+ float *fp, *dist, *maxdist, xyz[3];
float fac, d=0, fac1, fac2;
int a, tot, cycl=0;
- float *ft;
+
/* in a path vertices are with equal differences: path->len = number of verts */
/* NOW WITH BEVELCURVE!!! */
@@ -133,19 +134,12 @@ void calc_curvepath(Object *ob)
*fp= 0;
for(a=0; a<tot; a++) {
fp++;
- if(cycl && a==tot-1) {
- x= bevpfirst->x - bevp->x;
- y= bevpfirst->y - bevp->y;
- z= bevpfirst->z - bevp->z;
- }
- else {
- tempbevp = bevp+1;
- x= (tempbevp)->x - bevp->x;
- y= (tempbevp)->y - bevp->y;
- z= (tempbevp)->z - bevp->z;
- }
- *fp= *(fp-1)+ (float)sqrt(x*x+y*y+z*z);
+ if(cycl && a==tot-1)
+ VecSubf(xyz, bevpfirst->vec, bevp->vec);
+ else
+ VecSubf(xyz, (bevp+1)->vec, bevp->vec);
+ *fp= *(fp-1)+VecLength(xyz);
bevp++;
}
@@ -153,7 +147,7 @@ void calc_curvepath(Object *ob)
/* the path verts in path->data */
/* now also with TILT value */
- ft= path->data = (float *)MEM_callocN(16*path->len, "pathdata");
+ pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*4*path->len, "pathdata"); // XXX - why *4? - in 2.4x each element was 4 and the size was 16, so better leave for now - Campbell
bevp= bevpfirst;
bevpn= bevp+1;
@@ -183,13 +177,13 @@ void calc_curvepath(Object *ob)
fac1= fac2/fac1;
fac2= 1.0f-fac1;
- ft[0]= fac1*bevp->x+ fac2*(bevpn)->x;
- ft[1]= fac1*bevp->y+ fac2*(bevpn)->y;
- ft[2]= fac1*bevp->z+ fac2*(bevpn)->z;
- ft[3]= fac1*bevp->alfa+ fac2*(bevpn)->alfa;
+ VecLerpf(pp->vec, bevp->vec, bevpn->vec, fac2);
+ pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
+ pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
+ QuatInterpol(pp->quat, bevp->quat, bevpn->quat, fac2);
+ NormalQuat(pp->quat);
- ft+= 4;
-
+ pp++;
}
MEM_freeN(dist);
@@ -213,13 +207,14 @@ int interval_test(int min, int max, int p1, int cycl)
/* warning, *vec needs FOUR items! */
/* ctime is normalized range <0-1> */
-int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK */
+int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
{
Curve *cu;
Nurb *nu;
BevList *bl;
Path *path;
- float *fp, *p0, *p1, *p2, *p3, fac;
+ PathPoint *pp, *p0, *p1, *p2, *p3;
+ float fac;
float data[4];
int cycl=0, s0, s1, s2, s3;
@@ -230,7 +225,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
return 0;
}
path= cu->path;
- fp= path->data;
+ pp= path->data;
/* test for cyclic */
bl= cu->bev.first;
@@ -249,19 +244,19 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
s2= interval_test(0, path->len-1-cycl, s1+1, cycl);
s3= interval_test(0, path->len-1-cycl, s1+2, cycl);
- p0= fp + 4*s0;
- p1= fp + 4*s1;
- p2= fp + 4*s2;
- p3= fp + 4*s3;
+ p0= pp + s0;
+ p1= pp + s1;
+ p2= pp + s2;
+ p3= pp + s3;
/* note, commented out for follow constraint */
//if(cu->flag & CU_FOLLOW) {
- set_afgeleide_four_ipo(1.0f-fac, data, KEY_BSPLINE);
+ key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE);
- dir[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ;
- dir[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ;
- dir[2]= data[0]*p0[2] + data[1]*p1[2] + data[2]*p2[2] + data[3]*p3[2] ;
+ dir[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ;
+ dir[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ;
+ dir[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ;
/* make compatible with vectoquat */
dir[0]= -dir[0];
@@ -272,16 +267,35 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
nu= cu->nurb.first;
/* make sure that first and last frame are included in the vectors here */
- if((nu->type & 7)==CU_POLY) set_four_ipo(1.0f-fac, data, KEY_LINEAR);
- else if((nu->type & 7)==CU_BEZIER) set_four_ipo(1.0f-fac, data, KEY_LINEAR);
- else if(s0==s1 || p2==p3) set_four_ipo(1.0f-fac, data, KEY_CARDINAL);
- else set_four_ipo(1.0f-fac, data, KEY_BSPLINE);
-
- vec[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ;
- vec[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ;
- vec[2]= data[0]*p0[2] + data[1]*p1[2] + data[2]*p2[2] + data[3]*p3[2] ;
+ if(nu->type == CU_POLY) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR);
+ else if(nu->type == CU_BEZIER) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR);
+ else if(s0==s1 || p2==p3) key_curve_position_weights(1.0f-fac, data, KEY_CARDINAL);
+ else key_curve_position_weights(1.0f-fac, data, KEY_BSPLINE);
+
+ vec[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; /* X */
+ vec[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; /* Y */
+ vec[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* Z */
+ vec[3]= data[0]*p0->vec[3] + data[1]*p1->vec[3] + data[2]*p2->vec[3] + data[3]*p3->vec[3] ; /* Tilt, should not be needed since we have quat still used */
+ /* Need to verify the quat interpolation is correct - XXX */
+
+ if (quat) {
+ float totfac, q1[4], q2[4];
+
+ totfac= data[0]+data[1];
+ QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
+ NormalQuat(q1);
+
+ totfac= data[2]+data[3];
+ QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
+ NormalQuat(q2);
+
+ totfac = data[0]+data[1]+data[2]+data[3];
+ QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
+ NormalQuat(quat);
+ }
- vec[3]= data[0]*p0[3] + data[1]*p1[3] + data[2]*p2[3] + data[3]*p3[3] ;
+ if(radius)
+ *radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius;
return 1;
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index df7004d3f6b..643aa6bc779 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -204,6 +204,32 @@ AnimData *BKE_copy_animdata (AnimData *adt)
return dadt;
}
+/* Make Local -------------------------------------------- */
+
+static void make_local_strips(ListBase *strips)
+{
+ NlaStrip *strip;
+
+ for(strip=strips->first; strip; strip=strip->next) {
+ if(strip->act) make_local_action(strip->act);
+ if(strip->remap && strip->remap->target) make_local_action(strip->remap->target);
+
+ make_local_strips(&strip->strips);
+ }
+}
+
+void BKE_animdata_make_local(AnimData *adt)
+{
+ NlaTrack *nlt;
+
+ if(adt->action) make_local_action(adt->action);
+ if(adt->tmpact) make_local_action(adt->tmpact);
+ if(adt->remap && adt->remap->target) make_local_action(adt->remap->target);
+
+ for(nlt=adt->nla_tracks.first; nlt; nlt=nlt->next)
+ make_local_strips(&nlt->strips);
+}
+
/* *********************************** */
/* KeyingSet API */
@@ -239,7 +265,7 @@ KS_Path *BKE_keyingset_find_destination (KeyingSet *ks, ID *id, const char group
if ((ksp->rna_path==0) || strcmp(rna_path, ksp->rna_path))
eq_path= 0;
- /* index */
+ /* index - need to compare whole-array setting too... */
if (ksp->array_index != array_index)
eq_index= 0;
@@ -412,7 +438,7 @@ void BKE_keyingsets_free (ListBase *list)
* - path: original path string (as stored in F-Curve data)
* - dst: destination string to write data to
*/
-short animsys_remap_path (AnimMapper *remap, char *path, char **dst)
+static short animsys_remap_path (AnimMapper *remap, char *path, char **dst)
{
/* is there a valid remapping table to use? */
//if (remap) {
@@ -1424,7 +1450,6 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re
* 'local' (i.e. belonging in the nearest ID-block that setting is related to, not a
* standard 'root') block are overridden by a larger 'user'
*/
-// FIXME?: we currently go over entire 'main' database...
void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
{
ID *id;
@@ -1448,8 +1473,11 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
* when there are no actions, don't go over database and loop over heaps of datablocks,
* which should ultimately be empty, since it is not possible for now to have any animation
* without some actions, and drivers wouldn't get affected by any state changes
+ *
+ * however, if there are some curves, we will need to make sure that their 'ctime' property gets
+ * set correctly, so this optimisation must be skipped in that case...
*/
- if (main->action.first == NULL) {
+ if ((main->action.first == NULL) && (main->curve.first == NULL)) {
if (G.f & G_DEBUG)
printf("\tNo Actions, so no animation needs to be evaluated...\n");
@@ -1483,6 +1511,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
* value of the curve gets set in case there's no animation for that
* - it needs to be set before animation is evaluated just so that
* animation can successfully override...
+ * - it shouldn't get set when calculating drivers...
*/
for (id= main->curve.first; id; id= id->next) {
AnimData *adt= BKE_animdata_from_id(id);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 31ae4d6cbec..5f74edb97d4 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -131,7 +131,6 @@ void free_bones (bArmature *arm)
void free_armature(bArmature *arm)
{
if (arm) {
- /* unlink_armature(arm);*/
free_bones(arm);
/* free editmode data */
@@ -668,10 +667,10 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
if(bone->segments > MAX_BBONE_SUBDIV)
bone->segments= MAX_BBONE_SUBDIV;
- forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], MAX_BBONE_SUBDIV, 4);
- forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, MAX_BBONE_SUBDIV, 4);
- forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, MAX_BBONE_SUBDIV, 4);
- forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1), roll2, data[0]+3, MAX_BBONE_SUBDIV, 4);
+ forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], MAX_BBONE_SUBDIV, 4*sizeof(float));
+ forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, MAX_BBONE_SUBDIV, 4*sizeof(float));
+ forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, MAX_BBONE_SUBDIV, 4*sizeof(float));
+ forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1), roll2, data[0]+3, MAX_BBONE_SUBDIV, 4*sizeof(float));
equalize_bezier(data[0], bone->segments); // note: does stride 4!
@@ -1988,10 +1987,14 @@ void chan_calc_mat(bPoseChannel *chan)
/* get scaling matrix */
SizeToMat3(chan->size, smat);
- /* rotations may either be quats or eulers (no rotation modes for now...) */
- if (chan->rotmode) {
- /* euler rotations (will cause gimble lock... no rotation order to solve that yet) */
- EulToMat3(chan->eul, rmat);
+ /* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
+ if (chan->rotmode > 0) {
+ /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
+ EulOToMat3(chan->eul, chan->rotmode, rmat);
+ }
+ else if (chan->rotmode == PCHAN_ROT_AXISANGLE) {
+ /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
+ AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat);
}
else {
/* quats are normalised before use to eliminate scaling issues */
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 5c62e434cb6..18f065b59d9 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -74,6 +74,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
BoidSettings *boids = bbd->part->boids;
ParticleEffectorCache *ec;
Object *priority_ob = NULL;
+ BoidParticle *bpa = pa->boid;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
float priority = 0.0f, len = 0.0f;
@@ -81,7 +82,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
/* first find out goal/predator with highest priority */
/* if rule->ob specified use it */
- if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != pa->stick_ob)) {
+ if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
PartDeflect *pd = gabr->ob->pd;
float vec_to_part[3];
@@ -104,7 +105,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
PartDeflect *pd = eob->pd;
/* skip current object */
- if(rule->type == eBoidRuleType_Goal && eob == pa->stick_ob)
+ if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
continue;
if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) {
@@ -169,10 +170,10 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
VECCOPY(bbd->goal_nor, nor);
}
}
- else if(rule->type == eBoidRuleType_Avoid && pa->boid->mode == eBoidMode_Climbing &&
+ else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing &&
priority > 2.0f * gabr->fear_factor) {
/* detach from surface and try to fly away from danger */
- VECCOPY(vec_to_part, pa->r_ve);
+ VECCOPY(vec_to_part, bpa->gravity);
VecMulf(vec_to_part, -1.0f);
}
@@ -205,6 +206,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
KDTreeNearest *ptn = NULL;
ParticleEffectorCache *ec;
ParticleTarget *pt;
+ BoidParticle *bpa = pa->boid;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float co1[3], vel1[3], co2[3], vel2[3];
float len, t, inp, t_min = 2.0f;
@@ -231,7 +233,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
Object *eob = ec->ob;
/* don't check with current ground object */
- if(eob == pa->stick_ob)
+ if(eob == bpa->ground)
continue;
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
@@ -558,18 +560,19 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
}
static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
{
+ BoidParticle *bpa = pa->boid;
BoidRuleAverageSpeed *asbr = (BoidRuleAverageSpeed*)rule;
float vec[3] = {0.0f, 0.0f, 0.0f};
if(asbr->wander > 0.0f) {
/* abuse pa->r_ave for wandering */
- pa->r_ave[0] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
- pa->r_ave[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
- pa->r_ave[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
+ bpa->wander[0] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
+ bpa->wander[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
+ bpa->wander[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
- Normalize(pa->r_ave);
+ Normalize(bpa->wander);
- VECCOPY(vec, pa->r_ave);
+ VECCOPY(vec, bpa->wander);
QuatMulVecf(pa->prev_state.rot, vec);
@@ -615,6 +618,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
ParticleTarget *pt;
ParticleData *epars;
ParticleData *enemy_pa = NULL;
+ BoidParticle *bpa;
/* friends & enemies */
float closest_enemy[3] = {0.0f,0.0f,0.0f};
float closest_dist = fbr->distance + 1.0f;
@@ -624,8 +628,10 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
/* calculate own group strength */
int neighbors = BLI_kdtree_range_search(bbd->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn);
- for(n=0; n<neighbors; n++)
- health += bbd->psys->particles[ptn[n].index].boid->health;
+ for(n=0; n<neighbors; n++) {
+ bpa = bbd->psys->particles[ptn[n].index].boid;
+ health += bpa->data.health;
+ }
f_strength += bbd->part->boids->strength * health;
@@ -642,7 +648,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
health = 0.0f;
for(n=0; n<neighbors; n++) {
- health += epars[ptn[n].index].boid->health;
+ bpa = epars[ptn[n].index].boid;
+ health += bpa->data.health;
if(n==0 && pt->mode==PTARGET_MODE_ENEMY && ptn[n].dist < closest_dist) {
VECCOPY(closest_enemy, ptn[n].co);
@@ -674,7 +681,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
/* must face enemy to fight */
if(Inpf(pa->prev_state.ave, enemy_dir)>0.5f) {
- enemy_pa->boid->health -= bbd->part->boids->strength * bbd->timestep * ((1.0f-bbd->part->boids->accuracy)*damage + bbd->part->boids->accuracy);
+ bpa = enemy_pa->boid;
+ bpa->data.health -= bbd->part->boids->strength * bbd->timestep * ((1.0f-bbd->part->boids->accuracy)*damage + bbd->part->boids->accuracy);
}
}
else {
@@ -683,7 +691,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
}
/* check if boid doesn't want to fight */
- if(pa->boid->health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) {
+ bpa = pa->boid;
+ if(bpa->data.health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) {
/* decide to flee */
if(closest_dist < fbr->flee_distance * fbr->distance) {
VecMulf(bbd->wanted_co, -1.0f);
@@ -721,18 +730,20 @@ static boid_rule_cb boid_rules[] = {
static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *pa)
{
- if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
- val->max_speed = boids->land_max_speed * pa->boid->health/boids->health;
+ BoidParticle *bpa = pa->boid;
+
+ if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
+ val->max_speed = boids->land_max_speed * bpa->data.health/boids->health;
val->max_acc = boids->land_max_acc * val->max_speed;
- val->max_ave = boids->land_max_ave * M_PI * pa->boid->health/boids->health;
+ val->max_ave = boids->land_max_ave * M_PI * bpa->data.health/boids->health;
val->min_speed = 0.0f; /* no minimum speed on land */
val->personal_space = boids->land_personal_space;
- val->jump_speed = boids->land_jump_speed * pa->boid->health/boids->health;
+ val->jump_speed = boids->land_jump_speed * bpa->data.health/boids->health;
}
else {
- val->max_speed = boids->air_max_speed * pa->boid->health/boids->health;
+ val->max_speed = boids->air_max_speed * bpa->data.health/boids->health;
val->max_acc = boids->air_max_acc * val->max_speed;
- val->max_ave = boids->air_max_ave * M_PI * pa->boid->health/boids->health;
+ val->max_ave = boids->air_max_ave * M_PI * bpa->data.health/boids->health;
val->min_speed = boids->air_min_speed * boids->air_max_speed;
val->personal_space = boids->air_personal_space;
val->jump_speed = 0.0f; /* no jumping in air */
@@ -740,11 +751,13 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *
}
static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *ground_co, float *ground_nor)
{
- if(pa->boid->mode == eBoidMode_Climbing) {
+ BoidParticle *bpa = pa->boid;
+
+ if(bpa->data.mode == eBoidMode_Climbing) {
SurfaceModifierData *surmd = NULL;
float x[3], v[3];
- surmd = (SurfaceModifierData *)modifiers_findByType ( pa->stick_ob, eModifierType_Surface );
+ surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface );
/* take surface velocity into account */
effector_find_co(bbd->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL);
@@ -753,7 +766,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
/* get actual position on surface */
effector_find_co(bbd->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL);
- return pa->stick_ob;
+ return bpa->ground;
}
else {
float zvec[3] = {0.0f, 0.0f, 2000.0f};
@@ -803,13 +816,15 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
}
static int boid_rule_applies(ParticleData *pa, BoidSettings *boids, BoidRule *rule)
{
+ BoidParticle *bpa = pa->boid;
+
if(rule==NULL)
return 0;
- if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing) && rule->flag & BOIDRULE_ON_LAND)
+ if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing) && rule->flag & BOIDRULE_ON_LAND)
return 1;
- if(pa->boid->mode==eBoidMode_InAir && rule->flag & BOIDRULE_IN_AIR)
+ if(bpa->data.mode==eBoidMode_InAir && rule->flag & BOIDRULE_IN_AIR)
return 1;
return 0;
@@ -835,12 +850,13 @@ void boids_precalc_rules(ParticleSettings *part, float cfra)
}
static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co, float *surface_nor)
{
+ BoidParticle *bpa = pa->boid;
float nor[3], vel[3];
VECCOPY(nor, surface_nor);
- /* gather apparent gravity to r_ve */
- VECADDFAC(pa->r_ve, pa->r_ve, surface_nor, -1.0);
- Normalize(pa->r_ve);
+ /* gather apparent gravity */
+ VECADDFAC(bpa->gravity, bpa->gravity, surface_nor, -1.0);
+ Normalize(bpa->gravity);
/* raise boid it's size from surface */
VecMulf(nor, pa->size * boids->height);
@@ -877,16 +893,17 @@ static int apply_boid_rule(BoidBrainData *bbd, BoidRule *rule, BoidValues *val,
}
static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa) {
BoidState *state = boids->states.first;
+ BoidParticle *bpa = pa->boid;
for(; state; state=state->next) {
- if(state->id==pa->boid->state_id)
+ if(state->id==bpa->data.state_id)
return state;
}
/* for some reason particle isn't at a valid state */
state = boids->states.first;
if(state)
- pa->boid->state_id = state->id;
+ bpa->data.state_id = state->id;
return state;
}
@@ -902,9 +919,11 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
BoidSettings *boids = bbd->part->boids;
BoidValues val;
BoidState *state = get_boid_state(boids, pa);
+ BoidParticle *bpa = pa->boid;
+ int rand;
//BoidCondition *cond;
- if(pa->boid->health <= 0.0f) {
+ if(bpa->data.health <= 0.0f) {
pa->alive = PARS_DYING;
return;
}
@@ -922,7 +941,9 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f;
/* create random seed for every particle & frame */
- BLI_srandom(bbd->psys->seed + p + (int)bbd->cfra + (int)(1000*pa->r_rot[0]));
+ BLI_srandom(bbd->psys->seed + p);
+ rand = BLI_rand();
+ BLI_srandom((int)bbd->cfra + rand);
set_boid_values(&val, bbd->part->boids, pa);
@@ -939,7 +960,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
case eBoidRulesetType_Random:
{
/* use random rule for each particle (allways same for same particle though) */
- rule = BLI_findlink(&state->rules, (int)(1000.0f * pa->r_rot[1]) % BLI_countlist(&state->rules));
+ rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules));
apply_boid_rule(bbd, rule, &val, pa, -1.0);
}
@@ -969,7 +990,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
}
/* decide on jumping & liftoff */
- if(pa->boid->mode == eBoidMode_OnLand) {
+ if(bpa->data.mode == eBoidMode_OnLand) {
/* fuzziness makes boids capable of misjudgement */
float mul = 1.0 + state->rule_fuzziness;
@@ -983,7 +1004,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
Normalize2(cvel);
if(Inp2f(cvel, dir) > 0.95 / mul)
- pa->boid->mode = eBoidMode_Liftoff;
+ bpa->data.mode = eBoidMode_Liftoff;
}
else if(val.jump_speed > 0.0f) {
float jump_v[3];
@@ -1036,7 +1057,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
if(jump) {
VECCOPY(pa->prev_state.vel, jump_v);
- pa->boid->mode = eBoidMode_Falling;
+ bpa->data.mode = eBoidMode_Falling;
}
}
}
@@ -1045,6 +1066,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
void boid_body(BoidBrainData *bbd, ParticleData *pa)
{
BoidSettings *boids = bbd->part->boids;
+ BoidParticle *bpa = pa->boid;
BoidValues val;
float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3];
float dvec[3], bvec[3];
@@ -1066,10 +1088,10 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
pa_mass*=pa->size;
/* if boids can't fly they fall to the ground */
- if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f)
- pa->boid->mode = eBoidMode_Falling;
+ if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f)
+ bpa->data.mode = eBoidMode_Falling;
- if(pa->boid->mode == eBoidMode_Falling) {
+ if(bpa->data.mode == eBoidMode_Falling) {
/* Falling boids are only effected by gravity. */
acc[2] = bbd->part->acc[2];
}
@@ -1079,14 +1101,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
float level = landing_level + 1.0f;
float new_vel[3];
- if(pa->boid->mode == eBoidMode_Liftoff) {
- pa->boid->mode = eBoidMode_InAir;
- pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor);
+ if(bpa->data.mode == eBoidMode_Liftoff) {
+ bpa->data.mode = eBoidMode_InAir;
+ bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
}
- else if(pa->boid->mode == eBoidMode_InAir && boids->options & BOID_ALLOW_LAND) {
+ else if(bpa->data.mode == eBoidMode_InAir && boids->options & BOID_ALLOW_LAND) {
/* auto-leveling & landing if close to ground */
- pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor);
+ bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
/* level = how many particle sizes above ground */
level = (pa->prev_state.co[2] - ground_co[2])/(2.0f * pa->size) - 0.5;
@@ -1097,7 +1119,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
if(level < 1.0f) {
bbd->wanted_co[0] = bbd->wanted_co[1] = bbd->wanted_co[2] = 0.0f;
bbd->wanted_speed = 0.0f;
- pa->boid->mode = eBoidMode_Falling;
+ bpa->data.mode = eBoidMode_Falling;
}
else if(level < landing_level) {
bbd->wanted_speed *= (level - 1.0f)/landing_level;
@@ -1188,7 +1210,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
/* account for effectors */
do_effectors(p, pa, &pa->state, bbd->scene, bbd->ob, bbd->psys, pa->state.co, force, tvel, bbd->dfra, bbd->cfra);
- if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
+ if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
float length = Normalize(force);
length = MAX2(0.0f, length - boids->land_stick_force);
@@ -1199,8 +1221,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
VecAddf(acc, acc, force);
/* store smoothed acceleration for nice banking etc. */
- VECADDFAC(pa->boid->acc, pa->boid->acc, acc, dtime);
- VecMulf(pa->boid->acc, 1.0f / (1.0f + dtime));
+ VECADDFAC(bpa->data.acc, bpa->data.acc, acc, dtime);
+ VecMulf(bpa->data.acc, 1.0f / (1.0f + dtime));
/* integrate new location & velocity */
@@ -1218,32 +1240,32 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
VECADDFAC(pa->state.vel, pa->state.vel, acc, dtime);
- if(pa->boid->mode != eBoidMode_InAir)
- pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor);
+ if(bpa->data.mode != eBoidMode_InAir)
+ bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
/* change modes, constrain movement & keep track of down vector */
- switch(pa->boid->mode) {
+ switch(bpa->data.mode) {
case eBoidMode_InAir:
{
float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f};
/* don't take forward acceleration into account (better banking) */
- if(Inpf(pa->boid->acc, pa->state.vel) > 0.0f) {
- Projf(dvec, pa->boid->acc, pa->state.vel);
- VecSubf(dvec, pa->boid->acc, dvec);
+ if(Inpf(bpa->data.acc, pa->state.vel) > 0.0f) {
+ Projf(dvec, bpa->data.acc, pa->state.vel);
+ VecSubf(dvec, bpa->data.acc, dvec);
}
else {
- VECCOPY(dvec, pa->boid->acc);
+ VECCOPY(dvec, bpa->data.acc);
}
- /* gather apparent gravity to r_ve */
- VECADDFAC(pa->r_ve, grav, dvec, -boids->banking);
- Normalize(pa->r_ve);
+ /* gather apparent gravity */
+ VECADDFAC(bpa->gravity, grav, dvec, -boids->banking);
+ Normalize(bpa->gravity);
/* stick boid on goal when close enough */
if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) {
- pa->boid->mode = eBoidMode_Climbing;
- pa->stick_ob = bbd->goal_ob;
+ bpa->data.mode = eBoidMode_Climbing;
+ bpa->ground = bbd->goal_ob;
boid_find_ground(bbd, pa, ground_co, ground_nor);
boid_climb(boids, pa, ground_co, ground_nor);
}
@@ -1251,7 +1273,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
else if(boids->options & BOID_ALLOW_LAND && pa->state.co[2] <= ground_co[2] + pa->size * boids->height) {
pa->state.co[2] = ground_co[2] + pa->size * boids->height;
pa->state.vel[2] = 0.0f;
- pa->boid->mode = eBoidMode_OnLand;
+ bpa->data.mode = eBoidMode_OnLand;
}
break;
}
@@ -1259,15 +1281,15 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
{
float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f};
- /* gather apparent gravity to r_ve */
- VECADDFAC(pa->r_ve, pa->r_ve, grav, dtime);
- Normalize(pa->r_ve);
+ /* gather apparent gravity */
+ VECADDFAC(bpa->gravity, bpa->gravity, grav, dtime);
+ Normalize(bpa->gravity);
if(boids->options & BOID_ALLOW_LAND) {
/* stick boid on goal when close enough */
if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) {
- pa->boid->mode = eBoidMode_Climbing;
- pa->stick_ob = bbd->goal_ob;
+ bpa->data.mode = eBoidMode_Climbing;
+ bpa->ground = bbd->goal_ob;
boid_find_ground(bbd, pa, ground_co, ground_nor);
boid_climb(boids, pa, ground_co, ground_nor);
}
@@ -1275,14 +1297,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
else if(pa->state.co[2] <= ground_co[2] + 1.01 * pa->size * boids->height){
pa->state.co[2] = ground_co[2] + pa->size * boids->height;
pa->state.vel[2] = 0.0f;
- pa->boid->mode = eBoidMode_OnLand;
+ bpa->data.mode = eBoidMode_OnLand;
}
/* if we're falling, can fly and want to go upwards lets fly */
else if(boids->options & BOID_ALLOW_FLIGHT && bbd->wanted_co[2] > 0.0f)
- pa->boid->mode = eBoidMode_InAir;
+ bpa->data.mode = eBoidMode_InAir;
}
else
- pa->boid->mode = eBoidMode_InAir;
+ bpa->data.mode = eBoidMode_InAir;
break;
}
case eBoidMode_Climbing:
@@ -1308,14 +1330,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
{
/* stick boid on goal when close enough */
if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) {
- pa->boid->mode = eBoidMode_Climbing;
- pa->stick_ob = bbd->goal_ob;
+ bpa->data.mode = eBoidMode_Climbing;
+ bpa->ground = bbd->goal_ob;
boid_find_ground(bbd, pa, ground_co, ground_nor);
boid_climb(boids, pa, ground_co, ground_nor);
}
/* ground is too far away so boid falls */
else if(pa->state.co[2]-ground_co[2] > 1.1 * pa->size * boids->height)
- pa->boid->mode = eBoidMode_Falling;
+ bpa->data.mode = eBoidMode_Falling;
else {
/* constrain to surface */
pa->state.co[2] = ground_co[2] + pa->size * boids->height;
@@ -1329,17 +1351,17 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
VECCOPY(grav, ground_nor);
VecMulf(grav, -1.0f);
- Projf(dvec, pa->boid->acc, pa->state.vel);
- VecSubf(dvec, pa->boid->acc, dvec);
+ Projf(dvec, bpa->data.acc, pa->state.vel);
+ VecSubf(dvec, bpa->data.acc, dvec);
- /* gather apparent gravity to r_ve */
- VECADDFAC(pa->r_ve, grav, dvec, -boids->banking);
- Normalize(pa->r_ve);
+ /* gather apparent gravity */
+ VECADDFAC(bpa->gravity, grav, dvec, -boids->banking);
+ Normalize(bpa->gravity);
}
else {
- /* gather negative surface normal to r_ve */
- VECADDFAC(pa->r_ve, pa->r_ve, ground_nor, -1.0f);
- Normalize(pa->r_ve);
+ /* gather negative surface normal */
+ VECADDFAC(bpa->gravity, bpa->gravity, ground_nor, -1.0f);
+ Normalize(bpa->gravity);
}
break;
}
@@ -1347,29 +1369,29 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
/* save direction to state.ave unless the boid is falling */
/* (boids can't effect their direction when falling) */
- if(pa->boid->mode!=eBoidMode_Falling && VecLength(pa->state.vel) > 0.1*pa->size) {
+ if(bpa->data.mode!=eBoidMode_Falling && VecLength(pa->state.vel) > 0.1*pa->size) {
VECCOPY(pa->state.ave, pa->state.vel);
Normalize(pa->state.ave);
}
/* apply damping */
- if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing))
+ if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing))
VecMulf(pa->state.vel, 1.0f - 0.2f*bbd->part->dampfac);
/* calculate rotation matrix based on forward & down vectors */
- if(pa->boid->mode == eBoidMode_InAir) {
+ if(bpa->data.mode == eBoidMode_InAir) {
VECCOPY(mat[0], pa->state.ave);
- Projf(dvec, pa->r_ve, pa->state.ave);
- VecSubf(mat[2], pa->r_ve, dvec);
+ Projf(dvec, bpa->gravity, pa->state.ave);
+ VecSubf(mat[2], bpa->gravity, dvec);
Normalize(mat[2]);
}
else {
- Projf(dvec, pa->state.ave, pa->r_ve);
+ Projf(dvec, pa->state.ave, bpa->gravity);
VecSubf(mat[0], pa->state.ave, dvec);
Normalize(mat[0]);
- VECCOPY(mat[2], pa->r_ve);
+ VECCOPY(mat[2], bpa->gravity);
}
VecMulf(mat[2], -1.0f);
Crossf(mat[1], mat[2], mat[0]);
diff --git a/source/blender/blenkernel/intern/booleanops.c b/source/blender/blenkernel/intern/booleanops.c
index b6d1f7612b0..76355045186 100644
--- a/source/blender/blenkernel/intern/booleanops.c
+++ b/source/blender/blenkernel/intern/booleanops.c
@@ -591,7 +591,7 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
MEM_freeN(mat);
/* update dag */
- DAG_object_flush_update(scene, ob_new, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob_new->id, OB_RECALC_DATA);
return 1;
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index bce4e1120be..76a26762abe 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -711,7 +711,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
}
}
-void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
+static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
{
Brush *brush= painter->brush;
BrushPainterCache *cache= &painter->cache;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 2d330748772..bd737ccdc3f 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -96,7 +96,7 @@ static CM_SOLVER_DEF solvers [] =
static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm);
static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
+static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
@@ -156,7 +156,7 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms->goalfrict = 0.0f;
}
-BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
+static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
{
unsigned int i;
BVHTree *bvhtree;
@@ -197,7 +197,7 @@ BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
return bvhtree;
}
-BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon)
+static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon)
{
unsigned int i;
BVHTree *bvhtree;
@@ -348,7 +348,7 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
BKE_ptcache_id_from_cloth(&pid, ob, clmd);
// don't do anything as long as we're in editmode!
- if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
+ if(pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT)
return;
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
@@ -497,23 +497,32 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
if(!do_init_cloth(ob, clmd, result, framenr))
return result;
+ if(framenr == startframe) {
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ do_init_cloth(ob, clmd, result, framenr);
+ cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+ return result;
+ }
+
/* try to read from cache */
cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
-
implicit_set_positions(clmd);
cloth_to_object (ob, clmd, result);
+ cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+
+ if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+ BKE_ptcache_write_cache(&pid, framenr);
+
return result;
}
else if(cache_result==PTCACHE_READ_OLD) {
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
-
implicit_set_positions(clmd);
-
cache->flag |= PTCACHE_SIMULATION_VALID;
}
else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
@@ -524,38 +533,25 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
return result;
}
- if(framenr == startframe) {
- if(cache->flag & PTCACHE_REDO_NEEDED) {
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
- do_init_cloth(ob, clmd, result, framenr);
- }
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
-
- /* don't write cache on first frame, but on second frame write
- * cache for frame 1 and 2 */
- }
- else {
- /* if on second frame, write cache for first frame */
- if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
- BKE_ptcache_write_cache(&pid, startframe);
-
- clmd->sim_parms->timescale *= framenr - cache->simframe;
+ /* if on second frame, write cache for first frame */
+ if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
+ BKE_ptcache_write_cache(&pid, startframe);
- /* do simulation */
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
+ clmd->sim_parms->timescale *= framenr - cache->simframe;
- if(!do_step_cloth(ob, clmd, result, framenr)) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
- }
- else
- BKE_ptcache_write_cache(&pid, framenr);
+ /* do simulation */
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
- cloth_to_object (ob, clmd, result);
+ if(!do_step_cloth(ob, clmd, result, framenr)) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ cache->last_exact= 0;
}
+ else
+ BKE_ptcache_write_cache(&pid, framenr);
+
+ cloth_to_object (ob, clmd, result);
return result;
}
@@ -1003,7 +999,7 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in
return 0;
}
-void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
+static void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
{
unsigned int i = 0;
@@ -1036,7 +1032,7 @@ void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgeli
BLI_edgehash_free ( cloth->edgehash, NULL );
}
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
+static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
{
Cloth *cloth = clmd->clothObject;
ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 37e9c93a108..8ef1c285370 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -313,7 +313,7 @@ gsl_poly_solve_quadratic (double a, double b, double c,
* See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation"
* page 4, left column
*/
-int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] )
+static int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] )
{
int num_sols = 0;
@@ -427,7 +427,7 @@ int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3
// w3 is not perfect
-void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 )
+static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 )
{
double tempV1[3], tempV2[3], tempV4[3];
double a,b,c,d,e,f;
@@ -726,7 +726,7 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap
return collpair;
}
-int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
{
int result = 0;
Cloth *cloth1;
@@ -891,7 +891,7 @@ static void findClosestPointsEE(float *x1, float *x2, float *x3, float *x4, floa
}
// calculates the distance of 2 edges
-float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3], float *out_a1, float *out_a2, float *out_normal)
+static float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3], float *out_a1, float *out_a2, float *out_normal)
{
float line1[3], line2[3], cross[3];
float length;
@@ -1065,7 +1065,7 @@ float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3
return 0;
}
-int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair )
+static int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair )
{
EdgeCollPair edgecollpair;
Cloth *cloth1=NULL;
@@ -1275,7 +1275,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat
return result;
}
-int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+static int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
{
Cloth *cloth1;
cloth1 = clmd->clothObject;
@@ -1392,7 +1392,7 @@ CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *nu
return objs;
}
-void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
+static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
{
int i;
@@ -1405,7 +1405,7 @@ void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModi
}
}
-int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
+static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
{
Cloth *cloth = clmd->clothObject;
int i=0, j = 0, numfaces = 0, numverts = 0;
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 26f9245abc7..8cd64ae2ece 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -502,8 +502,8 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr)
for(a=0; a<cuma->totpoint-1; a++, fp += 2*CM_RESOL) {
correct_bezpart(bezt[a].vec[1], bezt[a].vec[2], bezt[a+1].vec[0], bezt[a+1].vec[1]);
- forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a+1].vec[0][0], bezt[a+1].vec[1][0], fp, CM_RESOL-1, 2);
- forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a+1].vec[0][1], bezt[a+1].vec[1][1], fp+1, CM_RESOL-1, 2);
+ forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a+1].vec[0][0], bezt[a+1].vec[1][0], fp, CM_RESOL-1, 2*sizeof(float));
+ forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a+1].vec[0][1], bezt[a+1].vec[1][1], fp+1, CM_RESOL-1, 2*sizeof(float));
}
/* store first and last handle for extrapolation, unit length */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index a9611039dab..ad474fb7910 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -123,6 +123,7 @@ bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata,
if (ob) {
cob->ob = ob;
cob->type = datatype;
+ cob->rotOrder = EULER_ORDER_DEFAULT; // TODO: when objects have rotation order too, use that
Mat4CpyMat4(cob->matrix, ob->obmat);
}
else
@@ -139,6 +140,15 @@ bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata,
cob->pchan = (bPoseChannel *)subdata;
cob->type = datatype;
+ if (cob->pchan->rotmode > 0) {
+ /* should be some type of Euler order */
+ cob->rotOrder= cob->pchan->rotmode;
+ }
+ else {
+ /* Quats, so eulers should just use default order */
+ cob->rotOrder= EULER_ORDER_DEFAULT;
+ }
+
/* matrix in world-space */
Mat4MulMat4(cob->matrix, cob->pchan->pose_mat, ob->obmat);
}
@@ -666,6 +676,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
* (Hopefully all compilers will be happy with the lines with just a space on them. Those are
* really just to help this code easier to read)
*/
+// TODO: cope with getting rotation order...
#define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
{ \
ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
@@ -689,6 +700,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
* (Hopefully all compilers will be happy with the lines with just a space on them. Those are
* really just to help this code easier to read)
*/
+// TODO: cope with getting rotation order...
#define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
{ \
ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
@@ -797,11 +809,11 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
/* extract components of both matrices */
VECCOPY(loc, ct->matrix[3]);
- Mat4ToEul(ct->matrix, eul);
+ Mat4ToEulO(ct->matrix, eul, ct->rotOrder);
Mat4ToSize(ct->matrix, size);
VECCOPY(loco, invmat[3]);
- Mat4ToEul(invmat, eulo);
+ Mat4ToEulO(invmat, eulo, cob->rotOrder);
Mat4ToSize(invmat, sizo);
/* disable channels not enabled */
@@ -816,8 +828,8 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
/* make new target mat and offset mat */
- LocEulSizeToMat4(ct->matrix, loc, eul, size);
- LocEulSizeToMat4(invmat, loco, eulo, sizo);
+ LocEulOSizeToMat4(ct->matrix, loc, eul, size, ct->rotOrder);
+ LocEulOSizeToMat4(invmat, loco, eulo, sizo, cob->rotOrder);
/* multiply target (parent matrix) by offset (parent inverse) to get
* the effect of the parent that will be exherted on the owner
@@ -1152,7 +1164,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
if (VALID_CONS_TARGET(ct)) {
Curve *cu= ct->tar->data;
- float q[4], vec[4], dir[3], quat[4], x1;
+ float q[4], vec[4], dir[3], quat[4], radius, x1;
float totmat[4][4];
float curvetime;
@@ -1164,21 +1176,30 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
*/
/* only happens on reload file, but violates depsgraph still... fix! */
- if (cu->path==NULL || cu->path->data==NULL)
+ if (cu->path==NULL || cu->path->data==NULL)
makeDispListCurveTypes(cob->scene, ct->tar, 0);
if (cu->path && cu->path->data) {
- curvetime= bsystem_time(cob->scene, ct->tar, (float)ctime, 0.0) - data->offset;
-
-#if 0 // XXX old animation system
- if (calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
- curvetime /= cu->pathlen;
+ if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
+ /* animated position along curve depending on time */
+ curvetime= bsystem_time(cob->scene, ct->tar, ctime, 0.0) - data->offset;
+
+ /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
+ * but this will only work if it actually is animated...
+ *
+ * we firstly calculate the modulus of cu->ctime/cu->pathlen to clamp ctime within the 0.0 to 1.0 times pathlen
+ * range, then divide this (the modulus) by pathlen to get a value between 0.0 and 1.0
+ */
+ curvetime= fmod(cu->ctime, cu->pathlen) / cu->pathlen;
CLAMP(curvetime, 0.0, 1.0);
}
-#endif // XXX old animation system
+ else {
+ /* fixed position along curve */
+ curvetime= data->offset; // XXX might need a more sensible value
+ }
- if ( where_on_path(ct->tar, curvetime, vec, dir) ) {
- if (data->followflag) {
+ if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius) ) {
+ if (data->followflag & FOLLOWPATH_FOLLOW) {
vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat);
Normalize(dir);
@@ -1191,6 +1212,14 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
QuatToMat4(quat, totmat);
}
+
+ if (data->followflag & FOLLOWPATH_RADIUS) {
+ float tmat[4][4], rmat[4][4];
+ Mat4Scale(tmat, radius);
+ Mat4MulMat4(rmat, totmat, tmat);
+ Mat4CpyMat4(totmat, rmat);
+ }
+
VECCOPY(totmat[3], vec);
Mat4MulSerie(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -1208,7 +1237,8 @@ static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
/* only evaluate if there is a target */
if (VALID_CONS_TARGET(ct)) {
float obmat[4][4];
- float size[3], obsize[3];
+ float size[3];
+ bFollowPathConstraint *data= con->data;
/* get Object local transform (loc/rot/size) to determine transformation from path */
//object_to_mat4(ob, obmat);
@@ -1221,13 +1251,17 @@ static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
Mat4MulSerie(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
/* un-apply scaling caused by path */
- Mat4ToSize(cob->matrix, obsize);
- if (obsize[0])
- VecMulf(cob->matrix[0], size[0] / obsize[0]);
- if (obsize[1])
- VecMulf(cob->matrix[1], size[1] / obsize[1]);
- if (obsize[2])
- VecMulf(cob->matrix[2], size[2] / obsize[2]);
+ if ((data->followflag & FOLLOWPATH_RADIUS)==0) { /* XXX - assume that scale correction means that radius will have some scale error in it - Campbell */
+ float obsize[3];
+
+ Mat4ToSize(cob->matrix, obsize);
+ if (obsize[0])
+ VecMulf(cob->matrix[0], size[0] / obsize[0]);
+ if (obsize[1])
+ VecMulf(cob->matrix[1], size[1] / obsize[1]);
+ if (obsize[2])
+ VecMulf(cob->matrix[2], size[2] / obsize[2]);
+ }
}
}
@@ -1306,7 +1340,7 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t
VECCOPY(loc, cob->matrix[3]);
Mat4ToSize(cob->matrix, size);
- Mat4ToEul(cob->matrix, eul);
+ Mat4ToEulO(cob->matrix, eul, cob->rotOrder);
/* eulers: radians to degrees! */
eul[0] = (float)(eul[0] / M_PI * 180);
@@ -1341,7 +1375,7 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t
eul[1] = (float)(eul[1] / 180 * M_PI);
eul[2] = (float)(eul[2] / 180 * M_PI);
- LocEulSizeToMat4(cob->matrix, loc, eul, size);
+ LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder);
}
static bConstraintTypeInfo CTI_ROTLIMIT = {
@@ -1548,14 +1582,14 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
VECCOPY(loc, cob->matrix[3]);
Mat4ToSize(cob->matrix, size);
- Mat4ToEul(ct->matrix, eul);
- Mat4ToEul(cob->matrix, obeul);
+ Mat4ToEulO(ct->matrix, eul, ct->rotOrder);
+ Mat4ToEulO(cob->matrix, obeul, cob->rotOrder);
if ((data->flag & ROTLIKE_X)==0)
eul[0] = obeul[0];
else {
if (data->flag & ROTLIKE_OFFSET)
- euler_rot(eul, obeul[0], 'x');
+ eulerO_rot(eul, obeul[0], 'x', cob->rotOrder);
if (data->flag & ROTLIKE_X_INVERT)
eul[0] *= -1;
@@ -1565,7 +1599,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
eul[1] = obeul[1];
else {
if (data->flag & ROTLIKE_OFFSET)
- euler_rot(eul, obeul[1], 'y');
+ eulerO_rot(eul, obeul[1], 'y', cob->rotOrder);
if (data->flag & ROTLIKE_Y_INVERT)
eul[1] *= -1;
@@ -1575,14 +1609,14 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
eul[2] = obeul[2];
else {
if (data->flag & ROTLIKE_OFFSET)
- euler_rot(eul, obeul[2], 'z');
+ eulerO_rot(eul, obeul[2], 'z', cob->rotOrder);
if (data->flag & ROTLIKE_Z_INVERT)
eul[2] *= -1;
}
compatible_eul(eul, obeul);
- LocEulSizeToMat4(cob->matrix, loc, eul, size);
+ LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder);
}
}
@@ -2845,7 +2879,7 @@ static void clampto_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
*/
/* only happens on reload file, but violates depsgraph still... fix! */
- if (cu->path==NULL || cu->path->data==NULL)
+ if (cu->path==NULL || cu->path->data==NULL)
makeDispListCurveTypes(cob->scene, ct->tar, 0);
}
@@ -2956,7 +2990,7 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
}
/* 3. position on curve */
- if (where_on_path(ct->tar, curvetime, vec, dir) ) {
+ if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) {
Mat4One(totmat);
VECCOPY(totmat[3], vec);
@@ -3038,7 +3072,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
Mat4ToSize(ct->matrix, dvec);
break;
case 1: /* rotation (convert to degrees first) */
- Mat4ToEul(ct->matrix, dvec);
+ Mat4ToEulO(ct->matrix, dvec, cob->rotOrder);
for (i=0; i<3; i++)
dvec[i] = (float)(dvec[i] / M_PI * 180);
break;
@@ -3049,7 +3083,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
/* extract components of owner's matrix */
VECCOPY(loc, cob->matrix[3]);
- Mat4ToEul(cob->matrix, eul);
+ Mat4ToEulO(cob->matrix, eul, cob->rotOrder);
Mat4ToSize(cob->matrix, size);
/* determine where in range current transforms lie */
@@ -3104,7 +3138,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
}
/* apply to matrix */
- LocEulSizeToMat4(cob->matrix, loc, eul, size);
+ LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder);
}
}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 7dd868278f4..ea3fce9ffaf 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -65,11 +65,10 @@
#include "BKE_object.h"
#include "BKE_utildefines.h" // VECCOPY
-
/* globals */
/* local */
-int cu_isectLL(float *v1, float *v2, float *v3, float *v4,
+static int cu_isectLL(float *v1, float *v2, float *v3, float *v4,
short cox, short coy,
float *labda, float *mu, float *vec);
@@ -137,7 +136,7 @@ Curve *add_curve(char *name, int type)
cu= alloc_libblock(&G.main->curve, ID_CU, name);
cu->size[0]= cu->size[1]= cu->size[2]= 1.0;
- cu->flag= CU_FRONT+CU_BACK;
+ cu->flag= CU_FRONT|CU_BACK|CU_PATH_RADIUS;
cu->pathlen= 100;
cu->resolu= cu->resolv= 12;
cu->width= 1.0;
@@ -470,8 +469,11 @@ void test2DNurb(Nurb *nu)
BezTriple *bezt;
BPoint *bp;
int a;
+
+ if((nu->flag & CU_2D)==0)
+ return;
- if( nu->type== CU_BEZIER+CU_2D ) {
+ if(nu->type == CU_BEZIER) {
a= nu->pntsu;
bezt= nu->bezt;
while(a--) {
@@ -481,7 +483,7 @@ void test2DNurb(Nurb *nu)
bezt++;
}
}
- else if(nu->type & CU_2D) {
+ else {
a= nu->pntsu*nu->pntsv;
bp= nu->bp;
while(a--) {
@@ -497,7 +499,7 @@ void minmaxNurb(Nurb *nu, float *min, float *max)
BPoint *bp;
int a;
- if( (nu->type & 7)==CU_BEZIER ) {
+ if(nu->type == CU_BEZIER) {
a= nu->pntsu;
bezt= nu->bezt;
while(a--) {
@@ -594,7 +596,7 @@ static void makecyclicknots(float *knots, short pnts, short order)
void makeknots(Nurb *nu, short uv)
{
- if( (nu->type & 7)==CU_NURBS ) {
+ if(nu->type == CU_NURBS) {
if(uv == 1) {
if(nu->knotsu) MEM_freeN(nu->knotsu);
if(check_valid_nurb_u(nu)) {
@@ -850,7 +852,7 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
MEM_freeN(jend);
}
-void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu)
+void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu, int stride)
/* coord_array has to be 3*4*pntsu*resolu in size and zero-ed
* tilt_array and radius_array will be written to if valid */
{
@@ -934,10 +936,10 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
}
}
- coord_fp+= 3;
+ coord_fp = (float *)(((char *)coord_fp) + stride);
- if (tilt_fp) tilt_fp++;
- if (radius_fp) radius_fp++;
+ if (tilt_fp) tilt_fp = (float *)(((char *)tilt_fp) + stride);
+ if (radius_fp) radius_fp = (float *)(((char *)radius_fp) + stride);
u+= ustep;
}
@@ -968,12 +970,31 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i
for(a=0; a<=it; a++) {
*p= q0;
- p+= stride;
+ p = (float *)(((char *)p)+stride);
q0+= q1;
q1+= q2;
q2+= q3;
}
-}
+}
+
+static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride)
+{
+ /* note that these are not purpendicular to the curve
+ * they need to be rotated for this,
+ *
+ * This could also be optimized like forward_diff_bezier */
+ int a;
+ for(a=0; a<=it; a++) {
+ float t = (float)a / (float)it;
+
+ int i;
+ for(i=0; i<3; i++) {
+ p[i]= (-6*t + 6)*p0[i] + (18*t - 12)*p1[i] + (-18*t + 6)*p2[i] + (6*t)*p3[i];
+ }
+ Normalize(p);
+ p = (float *)(((char *)p)+stride);
+ }
+}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -1342,7 +1363,7 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp)
}
}
-int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, float *labda, float *mu, float *vec)
+static int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, float *labda, float *mu, float *vec)
{
/* return:
-1: colliniar
@@ -1387,8 +1408,8 @@ static short bevelinside(BevList *bl1,BevList *bl2)
/* take first vertex of possible hole */
bevp= (BevPoint *)(bl2+1);
- hvec1[0]= bevp->x;
- hvec1[1]= bevp->y;
+ hvec1[0]= bevp->vec[0];
+ hvec1[1]= bevp->vec[1];
hvec1[2]= 0.0;
VECCOPY(hvec2,hvec1);
hvec2[0]+=1000;
@@ -1401,16 +1422,16 @@ static short bevelinside(BevList *bl1,BevList *bl2)
prevbevp= bevp+(nr-1);
while(nr--) {
- min= prevbevp->y;
- max= bevp->y;
+ min= prevbevp->vec[0];
+ max= bevp->vec[1];
if(max<min) {
min= max;
- max= prevbevp->y;
+ max= prevbevp->vec[1];
}
if(min!=max) {
if(min<=hvec1[1] && max>=hvec1[1]) {
/* there's a transition, calc intersection point */
- mode= cu_isectLL(&(prevbevp->x),&(bevp->x),hvec1,hvec2,0,1,&lab,&mu,vec);
+ mode= cu_isectLL(prevbevp->vec, bevp->vec, hvec1, hvec2, 0, 1, &lab, &mu, vec);
/* if lab==0.0 or lab==1.0 then the edge intersects exactly a transition
only allow for one situation: we choose lab= 1.0
*/
@@ -1483,12 +1504,15 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
}
-static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, int resolu)
+static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, int resolu, int stride)
{
BezTriple *pprev, *next, *last;
float fac, dfac, t[4];
int a;
+ if(tilt_array==NULL && radius_array==NULL)
+ return;
+
last= nu->bezt+(nu->pntsu-1);
/* returns a point */
@@ -1511,11 +1535,13 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
for(a=0; a<resolu; a++, fac+= dfac) {
if (tilt_array) {
if (nu->tilt_interp==3) { /* May as well support for tilt also 2.47 ease interp */
- tilt_array[a] = prevbezt->alfa + (bezt->alfa - prevbezt->alfa)*(3.0f*fac*fac - 2.0f*fac*fac*fac);
+ *tilt_array = prevbezt->alfa + (bezt->alfa - prevbezt->alfa)*(3.0f*fac*fac - 2.0f*fac*fac*fac);
} else {
- set_four_ipo(fac, t, nu->tilt_interp);
- tilt_array[a]= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa;
+ key_curve_position_weights(fac, t, nu->tilt_interp);
+ *tilt_array= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa;
}
+
+ tilt_array = (float *)(((char *)tilt_array) + stride);
}
if (radius_array) {
@@ -1523,19 +1549,363 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
/* Support 2.47 ease interp
* Note! - this only takes the 2 points into account,
* giving much more localized results to changes in radius, sometimes you want that */
- radius_array[a] = prevbezt->radius + (bezt->radius - prevbezt->radius)*(3.0f*fac*fac - 2.0f*fac*fac*fac);
+ *radius_array = prevbezt->radius + (bezt->radius - prevbezt->radius)*(3.0f*fac*fac - 2.0f*fac*fac*fac);
} else {
/* reuse interpolation from tilt if we can */
if (tilt_array==NULL || nu->tilt_interp != nu->radius_interp) {
- set_four_ipo(fac, t, nu->radius_interp);
+ key_curve_position_weights(fac, t, nu->radius_interp);
}
- radius_array[a]= t[0]*pprev->radius + t[1]*prevbezt->radius + t[2]*bezt->radius + t[3]*next->radius;
+ *radius_array= t[0]*pprev->radius + t[1]*prevbezt->radius + t[2]*bezt->radius + t[3]*next->radius;
+ }
+
+ radius_array = (float *)(((char *)radius_array) + stride);
+ }
+ }
+}
+
+/* make_bevel_list_3D_* funcs, at a minimum these must
+ * fill in the bezp->quat and bezp->dir values */
+
+/* correct non-cyclic cases by copying direction and rotation
+ * values onto the first & last end-points */
+static void bevel_list_cyclic_fix(BevList *bl)
+{
+ BevPoint *bevp, *bevp1;
+
+ bevp= (BevPoint *)(bl+1);
+ bevp1= bevp+1;
+ QUATCOPY(bevp->quat, bevp1->quat);
+ VECCOPY(bevp->dir, bevp1->dir);
+ VECCOPY(bevp->tan, bevp1->tan);
+ bevp= (BevPoint *)(bl+1);
+ bevp+= (bl->nr-1);
+ bevp1= bevp-1;
+ QUATCOPY(bevp->quat, bevp1->quat);
+ VECCOPY(bevp->dir, bevp1->dir);
+ VECCOPY(bevp->tan, bevp1->tan);
+}
+/* utility for make_bevel_list_3D_* funcs */
+static void bevel_list_calc_bisect(BevList *bl)
+{
+ BevPoint *bevp2, *bevp1, *bevp0;
+ int nr;
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+ /* totally simple */
+ VecBisect3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+}
+static void bevel_list_flip_tangents(BevList *bl)
+{
+ BevPoint *bevp2, *bevp1, *bevp0;
+ int nr;
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+ if(VecAngle2(bevp0->tan, bevp1->tan) > 90)
+ VecNegf(bevp1->tan);
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+}
+/* apply user tilt */
+static void bevel_list_apply_tilt(BevList *bl)
+{
+ BevPoint *bevp2, *bevp1, *bevp0;
+ int nr;
+ float q[4];
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+ AxisAngleToQuat(q, bevp1->dir, bevp1->alfa);
+ QuatMul(bevp1->quat, q, bevp1->quat);
+ NormalQuat(bevp1->quat);
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+}
+/* smooth quats, this function should be optimized, it can get slow with many iterations. */
+static void bevel_list_smooth(BevList *bl, int smooth_iter)
+{
+ BevPoint *bevp2, *bevp1, *bevp0;
+ int nr;
+
+ float q[4];
+ float bevp0_quat[4];
+ int a;
+
+ for(a=0; a < smooth_iter; a++) {
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+
+ if(bl->poly== -1) { /* check its not cyclic */
+ /* skip the first point */
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ nr--;
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ nr--;
+
+ }
+
+ QUATCOPY(bevp0_quat, bevp0->quat);
+
+ while(nr--) {
+ /* interpolate quats */
+ float zaxis[3] = {0,0,1}, cross[3], q2[4];
+ QuatInterpol(q, bevp0_quat, bevp2->quat, 0.5);
+ NormalQuat(q);
+
+ QuatMulVecf(q, zaxis);
+ Crossf(cross, zaxis, bevp1->dir);
+ AxisAngleToQuat(q2, cross, NormalizedVecAngle2(zaxis, bevp1->dir));
+ NormalQuat(q2);
+
+ QUATCOPY(bevp0_quat, bevp1->quat);
+ QuatMul(q, q2, q);
+ QuatInterpol(bevp1->quat, bevp1->quat, q, 0.5);
+ NormalQuat(bevp1->quat);
+
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+ }
+}
+
+static void make_bevel_list_3D_zup(BevList *bl)
+{
+ BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */
+ int nr;
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+ /* totally simple */
+ VecBisect3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
+ vectoquat(bevp1->dir, 5, 1, bevp1->quat);
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+}
+
+static void make_bevel_list_3D_minimum_twist(BevList *bl)
+{
+ BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */
+ int nr;
+ float q[4];
+
+ float cross_tmp[3];
+
+ bevel_list_calc_bisect(bl);
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+
+ if(nr+4 > bl->nr) { /* first time and second time, otherwise first point adjusts last */
+ vectoquat(bevp1->dir, 5, 1, bevp1->quat);
+ }
+ else {
+ float angle= NormalizedVecAngle2(bevp0->dir, bevp1->dir);
+
+ if(angle > 0.0f) { /* otherwise we can keep as is */
+ Crossf(cross_tmp, bevp0->dir, bevp1->dir);
+ AxisAngleToQuat(q, cross_tmp, angle);
+ QuatMul(bevp1->quat, q, bevp0->quat);
}
+ else {
+ QUATCOPY(bevp1->quat, bevp0->quat);
+ }
+ }
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+
+ if(bl->poly != -1) { /* check for cyclic */
+
+ /* Need to correct for the start/end points not matching
+ * do this by calculating the tilt angle difference, then apply
+ * the rotation gradually over the entire curve
+ *
+ * note that the split is between last and second last, rather then first/last as youd expect.
+ *
+ * real order is like this
+ * 0,1,2,3,4 --> 1,2,3,4,0
+ *
+ * this is why we compare last with second last
+ * */
+ float vec_1[3]= {0,1,0}, vec_2[3]= {0,1,0}, angle, ang_fac, cross_tmp[3];
+
+ BevPoint *bevp_first;
+ BevPoint *bevp_last;
+
+
+ bevp_first= (BevPoint *)(bl+1);
+ bevp_first+= bl->nr-1;
+ bevp_last = bevp_first;
+ bevp_last--;
+
+ /* quats and vec's are normalized, should not need to re-normalize */
+ QuatMulVecf(bevp_first->quat, vec_1);
+ QuatMulVecf(bevp_last->quat, vec_2);
+ Normalize(vec_1);
+ Normalize(vec_2);
+
+ /* align the vector, can avoid this and it looks 98% OK but
+ * better to align the angle quat roll's before comparing */
+ {
+ Crossf(cross_tmp, bevp_last->dir, bevp_first->dir);
+ angle = NormalizedVecAngle2(bevp_first->dir, bevp_last->dir);
+ AxisAngleToQuat(q, cross_tmp, angle);
+ QuatMulVecf(q, vec_2);
}
+
+ angle= NormalizedVecAngle2(vec_1, vec_2);
+
+ /* flip rotation if needs be */
+ Crossf(cross_tmp, vec_1, vec_2);
+ Normalize(cross_tmp);
+ if(NormalizedVecAngle2(bevp_first->dir, cross_tmp) < 90/(180.0/M_PI))
+ angle = -angle;
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+ ang_fac= angle * (1.0f-((float)nr/bl->nr)); /* also works */
+
+ AxisAngleToQuat(q, bevp1->dir, ang_fac);
+ QuatMul(bevp1->quat, q, bevp1->quat);
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+ }
+}
+
+static void make_bevel_list_3D_tangent(BevList *bl)
+{
+ BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */
+ int nr;
+
+ float bevp0_tan[3], cross_tmp[3];
+
+ bevel_list_calc_bisect(bl);
+ if(bl->poly== -1) /* check its not cyclic */
+ bevel_list_cyclic_fix(bl); // XXX - run this now so tangents will be right before doing the flipping
+ bevel_list_flip_tangents(bl);
+
+ /* correct the tangents */
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ nr= bl->nr;
+ while(nr--) {
+
+ Crossf(cross_tmp, bevp1->tan, bevp1->dir);
+ Crossf(bevp1->tan, cross_tmp, bevp1->dir);
+ Normalize(bevp1->tan);
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
+ }
+
+
+ /* now for the real twist calc */
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
+
+ VECCOPY(bevp0_tan, bevp0->tan);
+
+ nr= bl->nr;
+ while(nr--) {
+
+ /* make perpendicular, modify tan in place, is ok */
+ float cross_tmp[3];
+ float zero[3] = {0,0,0};
+
+ Crossf(cross_tmp, bevp1->tan, bevp1->dir);
+ Normalize(cross_tmp);
+ triatoquat(zero, cross_tmp, bevp1->tan, bevp1->quat); /* XXX - could be faster */
+
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
}
}
+static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode)
+{
+ switch(twist_mode) {
+ case CU_TWIST_TANGENT:
+ make_bevel_list_3D_tangent(bl);
+ break;
+ case CU_TWIST_MINIMUM:
+ make_bevel_list_3D_minimum_twist(bl);
+ break;
+ default: /* CU_TWIST_Z_UP default, pre 2.49c */
+ make_bevel_list_3D_zup(bl);
+ }
+
+ if(bl->poly== -1) /* check its not cyclic */
+ bevel_list_cyclic_fix(bl);
+
+ if(smooth_iter)
+ bevel_list_smooth(bl, smooth_iter);
+
+ bevel_list_apply_tilt(bl);
+}
+
+
+
void makeBevelList(Object *ob)
{
/*
@@ -1550,9 +1920,7 @@ void makeBevelList(Object *ob)
BPoint *bp;
BevList *bl, *blnew, *blnext;
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
- float min, inp, x1, x2, y1, y2, vec[3];
- float *coord_array, *tilt_array=NULL, *radius_array=NULL, *coord_fp, *tilt_fp=NULL, *radius_fp=NULL;
- float *v1, *v2;
+ float min, inp, x1, x2, y1, y2;
struct bevelsort *sortdata, *sd, *sd1;
int a, b, nr, poly, resolu, len=0;
int do_tilt, do_radius;
@@ -1587,7 +1955,7 @@ void makeBevelList(Object *ob)
else
resolu= nu->resolu;
- if((nu->type & 7)==CU_POLY) {
+ if(nu->type == CU_POLY) {
len= nu->pntsu;
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList2");
BLI_addtail(&(cu->bev), bl);
@@ -1595,22 +1963,20 @@ void makeBevelList(Object *ob)
if(nu->flagu & CU_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bl->nr= len;
- bl->flag= 0;
+ bl->dupe_nr= 0;
bevp= (BevPoint *)(bl+1);
bp= nu->bp;
while(len--) {
- bevp->x= bp->vec[0];
- bevp->y= bp->vec[1];
- bevp->z= bp->vec[2];
+ VECCOPY(bevp->vec, bp->vec);
bevp->alfa= bp->alfa;
bevp->radius= bp->radius;
- bevp->f1= SELECT;
+ bevp->split_tag= TRUE;
bevp++;
bp++;
}
}
- else if((nu->type & 7)==CU_BEZIER) {
+ else if(nu->type == CU_BEZIER) {
len= resolu*(nu->pntsu+ (nu->flagu & CU_CYCLIC) -1)+1; /* in case last point is not cyclic */
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelBPoints");
@@ -1631,139 +1997,81 @@ void makeBevelList(Object *ob)
bezt++;
}
- coord_array= coord_fp= MEM_mallocN(3*sizeof(float)*(resolu+1), "makeBevelCoords");
-
- if(do_tilt)
- tilt_array= tilt_fp= MEM_callocN(sizeof(float)*(resolu+1), "makeBevelTilt");
-
- if (do_radius)
- radius_array= radius_fp= MEM_callocN(sizeof(float)*(resolu+1), "nakeBevelRadius");
-
while(a--) {
if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
-
- bevp->x= prevbezt->vec[1][0];
- bevp->y= prevbezt->vec[1][1];
- bevp->z= prevbezt->vec[1][2];
+
+ VECCOPY(bevp->vec, prevbezt->vec[1]);
bevp->alfa= prevbezt->alfa;
bevp->radius= prevbezt->radius;
- bevp->f1= SELECT;
- bevp->f2= 0;
+ bevp->split_tag= TRUE;
+ bevp->dupe_tag= FALSE;
bevp++;
bl->nr++;
- bl->flag= 1;
+ bl->dupe_nr= 1;
}
else {
- v1= prevbezt->vec[1];
- v2= bezt->vec[0];
-
/* always do all three, to prevent data hanging around */
- forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], coord_array, resolu, 3);
- forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], coord_array+1, resolu, 3);
- forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], coord_array+2, resolu, 3);
+ int j;
- if (do_tilt || do_radius)
- alfa_bezpart(prevbezt, bezt, nu, tilt_array, radius_array, resolu);
+ /* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */
+ for(j=0; j<3; j++) {
+ forward_diff_bezier( prevbezt->vec[1][j], prevbezt->vec[2][j],
+ bezt->vec[0][j], bezt->vec[1][j],
+ &(bevp->vec[j]), resolu, sizeof(BevPoint));
+ }
+
+ /* if both arrays are NULL do nothiong */
+ alfa_bezpart( prevbezt, bezt, nu,
+ do_tilt ? &bevp->alfa : NULL,
+ do_radius ? &bevp->radius : NULL,
+ resolu, sizeof(BevPoint));
+
+ if(cu->twist_mode==CU_TWIST_TANGENT) {
+ forward_diff_bezier_cotangent(
+ prevbezt->vec[1], prevbezt->vec[2],
+ bezt->vec[0], bezt->vec[1],
+ bevp->tan, resolu, sizeof(BevPoint));
+ }
+
/* indicate with handlecodes double points */
if(prevbezt->h1==prevbezt->h2) {
- if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->f1= SELECT;
+ if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->split_tag= TRUE;
}
else {
- if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->f1= SELECT;
- else if(prevbezt->h2==0 || prevbezt->h2==HD_VECT) bevp->f1= SELECT;
- }
-
- nr= resolu;
-
- coord_fp = coord_array;
- tilt_fp = tilt_array;
- radius_fp = radius_array;
-
- while(nr--) {
- bevp->x= coord_fp[0];
- bevp->y= coord_fp[1];
- bevp->z= coord_fp[2];
- coord_fp+=3;
-
- if (do_tilt) {
- bevp->alfa= *tilt_fp;
- tilt_fp++;
- }
-
- if (do_radius) {
- bevp->radius= *radius_fp;
- radius_fp++;
- }
- bevp++;
+ if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->split_tag= TRUE;
+ else if(prevbezt->h2==0 || prevbezt->h2==HD_VECT) bevp->split_tag= TRUE;
}
bl->nr+= resolu;
-
+ bevp+= resolu;
}
prevbezt= bezt;
bezt++;
}
- MEM_freeN(coord_array);
- if (do_tilt) MEM_freeN(tilt_array);
- if (do_radius) MEM_freeN(radius_array);
- coord_array = tilt_array = radius_array = NULL;
-
if((nu->flagu & CU_CYCLIC)==0) { /* not cyclic: endpoint */
- bevp->x= prevbezt->vec[1][0];
- bevp->y= prevbezt->vec[1][1];
- bevp->z= prevbezt->vec[1][2];
+ VECCOPY(bevp->vec, prevbezt->vec[1]);
bevp->alfa= prevbezt->alfa;
bevp->radius= prevbezt->radius;
bl->nr++;
}
}
- else if((nu->type & 7)==CU_NURBS) {
+ else if(nu->type == CU_NURBS) {
if(nu->pntsv==1) {
len= (resolu*SEGMENTSU(nu));
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList3");
BLI_addtail(&(cu->bev), bl);
bl->nr= len;
- bl->flag= 0;
+ bl->dupe_nr= 0;
if(nu->flagu & CU_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bevp= (BevPoint *)(bl+1);
-
- coord_array= coord_fp= MEM_callocN(3*sizeof(float)*len, "makeBevelCoords"); /* has to be zero-ed */
-
- if(do_tilt)
- tilt_array= tilt_fp= MEM_callocN(sizeof(float)*len, "makeBevelTilt");
- if (do_radius)
- radius_array= radius_fp= MEM_callocN(sizeof(float)*len, "nakeBevelRadius");
-
- makeNurbcurve(nu, coord_array, tilt_array, radius_array, resolu);
-
- while(len--) {
- bevp->x= coord_fp[0];
- bevp->y= coord_fp[1];
- bevp->z= coord_fp[2];
- coord_fp+=3;
-
- if (do_tilt) {
- bevp->alfa= *tilt_fp;
- tilt_fp++;
- }
-
- if (do_radius) {
- bevp->radius= *radius_fp;
- radius_fp++;
- }
-
-
- bevp->f1= bevp->f2= 0;
- bevp++;
- }
- MEM_freeN(coord_array);
- if (do_tilt) MEM_freeN(tilt_array);
- if (do_radius) MEM_freeN(radius_array);
- coord_array = tilt_array = radius_array = NULL;
+ makeNurbcurve( nu, &bevp->vec[0],
+ do_tilt ? &bevp->alfa : NULL,
+ do_radius ? &bevp->radius : NULL,
+ resolu, sizeof(BevPoint));
}
}
}
@@ -1779,11 +2087,11 @@ void makeBevelList(Object *ob)
bevp0= bevp1+(nr-1);
nr--;
while(nr--) {
- if( fabs(bevp0->x-bevp1->x)<0.00001 ) {
- if( fabs(bevp0->y-bevp1->y)<0.00001 ) {
- if( fabs(bevp0->z-bevp1->z)<0.00001 ) {
- bevp0->f2= SELECT;
- bl->flag++;
+ if( fabs(bevp0->vec[0]-bevp1->vec[0])<0.00001 ) {
+ if( fabs(bevp0->vec[1]-bevp1->vec[1])<0.00001 ) {
+ if( fabs(bevp0->vec[2]-bevp1->vec[2])<0.00001 ) {
+ bevp0->dupe_tag= TRUE;
+ bl->dupe_nr++;
}
}
}
@@ -1796,8 +2104,8 @@ void makeBevelList(Object *ob)
bl= cu->bev.first;
while(bl) {
blnext= bl->next;
- if(bl->nr && bl->flag) {
- nr= bl->nr- bl->flag+1; /* +1 because vectorbezier sets flag too */
+ if(bl->nr && bl->dupe_nr) {
+ nr= bl->nr- bl->dupe_nr+1; /* +1 because vectorbezier sets flag too */
blnew= MEM_mallocN(sizeof(BevList)+nr*sizeof(BevPoint), "makeBevelList4");
memcpy(blnew, bl, sizeof(BevList));
blnew->nr= 0;
@@ -1807,7 +2115,7 @@ void makeBevelList(Object *ob)
bevp1= (BevPoint *)(blnew+1);
nr= bl->nr;
while(nr--) {
- if(bevp0->f2==0) {
+ if(bevp0->dupe_tag==0) {
memcpy(bevp1, bevp0, sizeof(BevPoint));
bevp1++;
blnew->nr++;
@@ -1815,19 +2123,19 @@ void makeBevelList(Object *ob)
bevp0++;
}
MEM_freeN(bl);
- blnew->flag= 0;
+ blnew->dupe_nr= 0;
}
bl= blnext;
}
- /* STEP 3: COUNT POLYS TELLEN AND AUTOHOLE */
+ /* STEP 3: POLYS COUNT AND AUTOHOLE */
bl= cu->bev.first;
poly= 0;
while(bl) {
if(bl->nr && bl->poly>=0) {
poly++;
bl->poly= poly;
- bl->gat= 0; /* 'gat' is dutch for hole */
+ bl->hole= 0;
}
bl= bl->next;
}
@@ -1844,8 +2152,8 @@ void makeBevelList(Object *ob)
bevp= (BevPoint *)(bl+1);
nr= bl->nr;
while(nr--) {
- if(min>bevp->x) {
- min= bevp->x;
+ if(min>bevp->vec[0]) {
+ min= bevp->vec[0];
bevp1= bevp;
}
bevp++;
@@ -1860,8 +2168,7 @@ void makeBevelList(Object *ob)
if(bevp1== bevp) bevp2= (BevPoint *)(bl+1);
else bevp2= bevp1+1;
- inp= (bevp1->x- bevp0->x)*(bevp0->y- bevp2->y)
- +(bevp0->y- bevp1->y)*(bevp0->x- bevp2->x);
+ inp= (bevp1->vec[0]- bevp0->vec[0]) * (bevp0->vec[1]- bevp2->vec[1]) + (bevp0->vec[1]- bevp1->vec[1]) * (bevp0->vec[0]- bevp2->vec[0]);
if(inp>0.0) sd->dir= 1;
else sd->dir= 0;
@@ -1879,7 +2186,7 @@ void makeBevelList(Object *ob)
sd1= sortdata+ (a-1);
for(b=a-1; b>=0; b--, sd1--) { /* all polys to the left */
if(bevelinside(sd1->bl, bl)) {
- bl->gat= 1- sd1->bl->gat;
+ bl->hole= 1- sd1->bl->hole;
break;
}
}
@@ -1889,7 +2196,7 @@ void makeBevelList(Object *ob)
if((cu->flag & CU_3D)==0) {
sd= sortdata;
for(a=0; a<poly; a++, sd++) {
- if(sd->bl->gat==sd->dir) {
+ if(sd->bl->hole==sd->dir) {
bl= sd->bl;
bevp1= (BevPoint *)(bl+1);
bevp2= bevp1+ (bl->nr-1);
@@ -1905,104 +2212,90 @@ void makeBevelList(Object *ob)
MEM_freeN(sortdata);
}
- /* STEP 4: COSINES */
- bl= cu->bev.first;
- while(bl) {
-
- if(bl->nr==2) { /* 2 pnt, treat separate */
- bevp2= (BevPoint *)(bl+1);
- bevp1= bevp2+1;
+ /* STEP 4: 2D-COSINES or 3D ORIENTATION */
+ if((cu->flag & CU_3D)==0) { /* 3D */
+ bl= cu->bev.first;
+ while(bl) {
- x1= bevp1->x- bevp2->x;
- y1= bevp1->y- bevp2->y;
+ if(bl->nr < 2) {
+ /* do nothing */
+ }
+ else if(bl->nr==2) { /* 2 pnt, treat separate */
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+1;
- calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa));
- bevp2->sina= bevp1->sina;
- bevp2->cosa= bevp1->cosa;
+ x1= bevp1->vec[0]- bevp2->vec[0];
+ y1= bevp1->vec[1]- bevp2->vec[1];
- if(cu->flag & CU_3D) { /* 3D */
- float quat[4], q[4];
-
- vec[0]= bevp1->x - bevp2->x;
- vec[1]= bevp1->y - bevp2->y;
- vec[2]= bevp1->z - bevp2->z;
-
- vectoquat(vec, 5, 1, quat);
-
- Normalize(vec);
- q[0]= (float)cos(0.5*bevp1->alfa);
- x1= (float)sin(0.5*bevp1->alfa);
- q[1]= x1*vec[0];
- q[2]= x1*vec[1];
- q[3]= x1*vec[2];
- QuatMul(quat, q, quat);
-
- QuatToMat3(quat, bevp1->mat);
- Mat3CpyMat3(bevp2->mat, bevp1->mat);
+ calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa));
+ bevp2->sina= bevp1->sina;
+ bevp2->cosa= bevp1->cosa;
}
+ else {
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+(bl->nr-1);
+ bevp0= bevp1-1;
- }
- else if(bl->nr>2) {
- bevp2= (BevPoint *)(bl+1);
- bevp1= bevp2+(bl->nr-1);
- bevp0= bevp1-1;
+ nr= bl->nr;
+ while(nr--) {
+ x1= bevp1->vec[0]- bevp0->vec[0];
+ x2= bevp1->vec[0]- bevp2->vec[0];
+ y1= bevp1->vec[1]- bevp0->vec[1];
+ y2= bevp1->vec[1]- bevp2->vec[1];
-
- nr= bl->nr;
-
- while(nr--) {
-
- if(cu->flag & CU_3D) { /* 3D */
- float quat[4], q[4];
-
- vec[0]= bevp2->x - bevp0->x;
- vec[1]= bevp2->y - bevp0->y;
- vec[2]= bevp2->z - bevp0->z;
-
- Normalize(vec);
+ calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
- vectoquat(vec, 5, 1, quat);
-
- q[0]= (float)cos(0.5*bevp1->alfa);
- x1= (float)sin(0.5*bevp1->alfa);
- q[1]= x1*vec[0];
- q[2]= x1*vec[1];
- q[3]= x1*vec[2];
- QuatMul(quat, q, quat);
-
- QuatToMat3(quat, bevp1->mat);
+ bevp0= bevp1;
+ bevp1= bevp2;
+ bevp2++;
}
-
- x1= bevp1->x- bevp0->x;
- x2= bevp1->x- bevp2->x;
- y1= bevp1->y- bevp0->y;
- y2= bevp1->y- bevp2->y;
-
- calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
-
-
- bevp0= bevp1;
- bevp1= bevp2;
- bevp2++;
- }
- /* correct non-cyclic cases */
- if(bl->poly== -1) {
- if(bl->nr>2) {
+
+ /* correct non-cyclic cases */
+ if(bl->poly== -1) {
bevp= (BevPoint *)(bl+1);
bevp1= bevp+1;
bevp->sina= bevp1->sina;
bevp->cosa= bevp1->cosa;
- Mat3CpyMat3(bevp->mat, bevp1->mat);
bevp= (BevPoint *)(bl+1);
bevp+= (bl->nr-1);
bevp1= bevp-1;
bevp->sina= bevp1->sina;
bevp->cosa= bevp1->cosa;
- Mat3CpyMat3(bevp->mat, bevp1->mat);
}
}
+ bl= bl->next;
+ }
+ }
+ else { /* 3D Curves */
+ bl= cu->bev.first;
+ while(bl) {
+
+ if(bl->nr < 2) {
+ /* do nothing */
+ }
+ else if(bl->nr==2) { /* 2 pnt, treat separate */
+ float q[4];
+
+ bevp2= (BevPoint *)(bl+1);
+ bevp1= bevp2+1;
+
+ /* simple quat/dir */
+ VecSubf(bevp1->dir, bevp1->vec, bevp2->vec);
+ Normalize(bevp1->dir);
+
+ vectoquat(bevp1->dir, 5, 1, bevp1->quat);
+
+ AxisAngleToQuat(q, bevp1->dir, bevp1->alfa);
+ QuatMul(bevp1->quat, q, bevp1->quat);
+ NormalQuat(bevp1->quat);
+ VECCOPY(bevp2->dir, bevp1->dir);
+ QUATCOPY(bevp2->quat, bevp1->quat);
+ }
+ else {
+ make_bevel_list_3D(bl, (int)(resolu*cu->twist_smooth), cu->twist_mode);
+ }
+ bl= bl->next;
}
- bl= bl->next;
}
}
@@ -2207,7 +2500,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
BezTriple *bezt, *prev, *next;
short a;
- if((nu->type & 7)!=CU_BEZIER) return;
+ if(nu->type != CU_BEZIER) return;
if(nu->pntsu<2) return;
a= nu->pntsu;
@@ -2242,7 +2535,7 @@ void testhandlesNurb(Nurb *nu)
BezTriple *bezt;
short flag, a;
- if((nu->type & 7)!=CU_BEZIER) return;
+ if(nu->type != CU_BEZIER) return;
bezt= nu->bezt;
a= nu->pntsu;
@@ -2370,7 +2663,7 @@ void sethandlesNurb(ListBase *editnurb, short code)
if(code==1 || code==2) {
nu= editnurb->first;
while(nu) {
- if( (nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
@@ -2400,7 +2693,7 @@ void sethandlesNurb(ListBase *editnurb, short code)
} else {
/* Toggle */
while(nu) {
- if( (nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
@@ -2417,7 +2710,7 @@ void sethandlesNurb(ListBase *editnurb, short code)
}
nu= editnurb->first;
while(nu) {
- if( (nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
@@ -2465,7 +2758,7 @@ void switchdirectionNurb(Nurb *nu)
if(nu->pntsu==1 && nu->pntsv==1) return;
- if((nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
a= nu->pntsu;
bezt1= nu->bezt;
bezt2= bezt1+(a-1);
@@ -2504,7 +2797,7 @@ void switchdirectionNurb(Nurb *nu)
bp1++;
bp2--;
}
- if((nu->type & 7)==CU_NURBS) {
+ if(nu->type == CU_NURBS) {
/* inverse knots */
a= KNOTSU(nu);
fp1= nu->knotsu;
@@ -2567,7 +2860,7 @@ float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3]
co = cos[0];
for (nu=lb->first; nu; nu=nu->next) {
- if ((nu->type & 7)==CU_BEZIER) {
+ if (nu->type == CU_BEZIER) {
BezTriple *bezt = nu->bezt;
for (i=0; i<nu->pntsu; i++,bezt++) {
@@ -2594,7 +2887,7 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
int i;
for (nu=lb->first; nu; nu=nu->next) {
- if ((nu->type & 7)==CU_BEZIER) {
+ if (nu->type == CU_BEZIER) {
BezTriple *bezt = nu->bezt;
for (i=0; i<nu->pntsu; i++,bezt++) {
@@ -2616,7 +2909,7 @@ int check_valid_nurb_u( struct Nurb *nu )
{
if (nu==NULL) return 0;
if (nu->pntsu <= 1) return 0;
- if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */
+ if (nu->type != CU_NURBS) return 1; /* not a nurb, lets assume its valid */
if (nu->pntsu < nu->orderu) return 0;
if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagu>>1) & 2)) { /* Bezier U Endpoints */
@@ -2630,7 +2923,7 @@ int check_valid_nurb_v( struct Nurb *nu)
{
if (nu==NULL) return 0;
if (nu->pntsv <= 1) return 0;
- if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */
+ if (nu->type != CU_NURBS) return 1; /* not a nurb, lets assume its valid */
if (nu->pntsv < nu->orderv) return 0;
if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagv>>1) & 2)) { /* Bezier V Endpoints */
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 6c765b02e5d..58f3db50d0f 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -61,6 +61,7 @@
#include "DNA_space_types.h"
#include "DNA_view2d_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
#include "BLI_ghash.h"
@@ -77,6 +78,7 @@
#include "BKE_pointcache.h"
#include "BKE_utildefines.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "MEM_guardedalloc.h"
@@ -2141,43 +2143,106 @@ void DAG_scene_update_flags(Scene *scene, unsigned int lay)
}
+static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay)
+{
+ wmWindowManager *wm;
+ wmWindow *win;
+
+ /* only one scene supported currently, making more scenes work
+ correctly requires changes beyond just the dependency graph */
+
+ *sce= NULL;
+ *lay= 0;
+
+ if((wm= bmain->wm.first)) {
+ /* if we have a windowmanager, look into windows */
+ for(win=wm->windows.first; win; win=win->next) {
+ if(win->screen) {
+ if(!*sce) *sce= win->screen->scene;
+ *lay |= BKE_screen_visible_layers(win->screen);
+ }
+ }
+ }
+ else {
+ /* if not, use the first sce */
+ *sce= bmain->scene.first;
+ if(*sce) *lay= (*sce)->lay;
-/* flag this object and all its relations to recalc */
-/* if you need to do more objects, tag object yourself and
- use DAG_scene_flush_update() in end */
-void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
+ /* XXX for background mode, we should get the scen
+ from somewhere, for the -S option, but it's in
+ the context, how to get it here? */
+ }
+}
+
+void DAG_ids_flush_update(int time)
{
-
- if(ob==NULL || sce->theDag==NULL) return;
+ Main *bmain= G.main;
+ Scene *sce;
+ unsigned int lay;
- ob->recalc |= flag;
- BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
-
- /* all users of this ob->data should be checked */
- /* BUT! displists for curves are still only on cu */
- if(flag & OB_RECALC_DATA) {
- if(ob->type!=OB_CURVE && ob->type!=OB_SURF) {
- ID *id= ob->data;
- if(id && id->us>1) {
- /* except when there's a key and shapes are locked */
- if(ob_get_key(ob) && (ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)));
- else {
- Object *obt;
- for (obt=G.main->object.first; obt; obt= obt->id.next) {
- if (obt != ob && obt->data==ob->data) {
- obt->recalc |= OB_RECALC_DATA;
- BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
- }
- }
+ dag_current_scene_layers(bmain, &sce, &lay);
+
+ if(sce)
+ DAG_scene_flush_update(sce, lay, time);
+}
+
+void DAG_id_flush_update(ID *id, short flag)
+{
+ Main *bmain= G.main;
+ Scene *sce;
+ Object *obt, *ob= NULL;
+ short idtype;
+ unsigned int lay;
+
+ dag_current_scene_layers(bmain, &sce, &lay);
+
+ if(!id || !sce || !sce->theDag)
+ return;
+
+ /* set flags & pointcache for object */
+ if(GS(id->name) == ID_OB) {
+ ob= (Object*)id;
+ ob->recalc |= flag;
+ BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
+
+ if(flag & OB_RECALC_DATA) {
+ /* all users of this ob->data should be checked */
+ id= ob->data;
+
+ /* no point in trying in this cases */
+ if(!id || id->us <= 1)
+ id= NULL;
+ /* curves and surfaces only need to mark one object, since
+ otherwise cu->displist would be computed multiple times */
+ else if(ob->type==OB_CURVE || ob->type==OB_SURF)
+ id= NULL;
+ /* also for locked shape keys we make an exception */
+ else if(ob_get_key(ob) && (ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)))
+ id= NULL;
+ }
+ }
+
+ /* set flags & pointcache for object data */
+ if(id) {
+ idtype= GS(id->name);
+
+ if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) {
+ for(obt=bmain->object.first; obt; obt= obt->id.next) {
+ if(!(ob && obt == ob) && obt->data == id) {
+ obt->recalc |= OB_RECALC_DATA;
+ BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
+
+ /* for these we only flag one object, otherwise cu->displist
+ would be computed multiple times */
+ if(obt->type==OB_CURVE || obt->type==OB_SURF)
+ break;
}
}
}
}
-
-// XXX if(G.curscreen)
-// DAG_scene_flush_update(sce, dag_screen_view3d_layers(), 0);
-// else
- DAG_scene_flush_update(sce, sce->lay, 0);
+
+ /* flush to other objects that depend on this one */
+ DAG_scene_flush_update(sce, lay, 0);
}
/* recursively descends tree, each node only checked once */
@@ -2212,10 +2277,25 @@ static int parent_check_node(DagNode *node, int curtime)
/* all nodes that influence this object get tagged, for calculating the exact
position of this object at a given timeframe */
-void DAG_object_update_flags(Scene *sce, Object *ob, unsigned int lay)
+void DAG_id_update_flags(ID *id)
{
+ Main *bmain= G.main;
+ Scene *sce;
DagNode *node;
DagAdjList *itA;
+ Object *ob;
+ unsigned int lay;
+
+ dag_current_scene_layers(bmain, &sce, &lay);
+
+ if(!id || !sce || !sce->theDag)
+ return;
+
+ /* objects only currently */
+ if(GS(id->name) != ID_OB)
+ return;
+
+ ob= (Object*)id;
/* tag nodes unchecked */
for(node = sce->theDag->DagNode.first; node; node= node->next)
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 6f897be9b05..d8f466835b3 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -821,7 +821,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
DispList *dl;
BezTriple *bezt, *prevbezt;
BPoint *bp;
- float *data, *v1, *v2;
+ float *data;
int a, len, resolu;
nu= nubase->first;
@@ -834,7 +834,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
resolu= nu->resolu;
if(!check_valid_nurb_u(nu));
- else if((nu->type & 7)==CU_BEZIER) {
+ else if(nu->type == CU_BEZIER) {
/* count */
len= 0;
@@ -886,11 +886,15 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
data+= 3;
}
else {
- v1= prevbezt->vec[1];
- v2= bezt->vec[0];
- forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, resolu, 3);
- forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, resolu, 3);
- forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, resolu, 3);
+ int j;
+ for(j=0; j<3; j++) {
+ forward_diff_bezier( prevbezt->vec[1][j],
+ prevbezt->vec[2][j],
+ bezt->vec[0][j],
+ bezt->vec[1][j],
+ data+j, resolu, 3*sizeof(float));
+ }
+
data+= 3*resolu;
}
@@ -902,7 +906,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
bezt++;
}
}
- else if((nu->type & 7)==CU_NURBS) {
+ else if(nu->type == CU_NURBS) {
len= (resolu*SEGMENTSU(nu));
dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
@@ -917,9 +921,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
data= dl->verts;
if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
else dl->type= DL_SEGM;
- makeNurbcurve(nu, data, NULL, NULL, resolu);
+ makeNurbcurve(nu, data, NULL, NULL, resolu, 3*sizeof(float));
}
- else if((nu->type & 7)==CU_POLY) {
+ else if(nu->type == CU_POLY) {
len= nu->pntsu;
dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
@@ -1127,7 +1131,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
}
-void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
+static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
{
if(cu->flag & CU_3D) return;
@@ -1424,7 +1428,7 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
else dl->type= DL_SEGM;
- makeNurbcurve(nu, data, NULL, NULL, nu->resolu);
+ makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float));
}
else {
len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv);
@@ -1539,9 +1543,9 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
bevp= (BevPoint *)(bl+1);
data= dl->verts;
while(a--) {
- data[0]= bevp->x+widfac*bevp->sina;
- data[1]= bevp->y+widfac*bevp->cosa;
- data[2]= bevp->z;
+ data[0]= bevp->vec[0]+widfac*bevp->sina;
+ data[1]= bevp->vec[1]+widfac*bevp->cosa;
+ data[2]= bevp->vec[2];
bevp++;
data+=3;
}
@@ -1581,7 +1585,7 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
fac = calc_taper(scene, cu->taperobj, a, bl->nr);
}
- if (bevp->f1) {
+ if (bevp->split_tag) {
dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
}
@@ -1595,16 +1599,16 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
vec[1]= fp1[2];
vec[2]= 0.0;
- Mat3MulVecfl(bevp->mat, vec);
+ QuatMulVecf(bevp->quat, vec);
- data[0]= bevp->x+ fac*vec[0];
- data[1]= bevp->y+ fac*vec[1];
- data[2]= bevp->z+ fac*vec[2];
+ data[0]= bevp->vec[0] + fac*vec[0];
+ data[1]= bevp->vec[1] + fac*vec[1];
+ data[2]= bevp->vec[2] + fac*vec[2];
}
else {
- data[0]= bevp->x+ fac*(widfac+fp1[1])*bevp->sina;
- data[1]= bevp->y+ fac*(widfac+fp1[1])*bevp->cosa;
- data[2]= bevp->z+ fac*fp1[2];
+ data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina;
+ data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa;
+ data[2]= bevp->vec[2] + fac*fp1[2];
}
}
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 31f6e2c6067..54d2f85457f 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -916,7 +916,7 @@ void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
}
/* find root ('zero') */
-int findzero (float x, float q0, float q1, float q2, float q3, float *o)
+static int findzero (float x, float q0, float q1, float q2, float q3, float *o)
{
double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
int nr= 0;
@@ -1010,7 +1010,7 @@ int findzero (float x, float q0, float q1, float q2, float q3, float *o)
}
}
-void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
+static void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
{
float t, c0, c1, c2, c3;
int a;
@@ -1026,7 +1026,7 @@ void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
}
}
-void berekenx (float *f, float *o, int b)
+static void berekenx (float *f, float *o, int b)
{
float t, c0, c1, c2, c3;
int a;
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 0024f84d8fb..2233bbbf328 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -80,6 +80,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
if(!fss)
return;
+ fss->fmd = fluidmd;
fss->type = OB_FLUIDSIM_ENABLE;
fss->show_advancedoptions = 0;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 70901778585..4e05bf45d3d 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -129,7 +129,7 @@ wcsleninu8(wchar_t *src)
}
int
-utf8slen(char *src)
+static utf8slen(char *src)
{
int size = 0, index = 0;
unsigned char c;
@@ -462,7 +462,7 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i
nu2->resolu= cu->resolu;
nu2->bezt = NULL;
nu2->knotsu = nu2->knotsv = NULL;
- nu2->flag= 0;
+ nu2->flag= CU_2D;
nu2->charidx = charidx+1000;
if (mat_nr > 0) nu2->mat_nr= mat_nr-1;
nu2->pntsu = 4;
@@ -495,7 +495,6 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i
nu2->bp[3].vec[2] = 0;
nu2->bp[3].vec[3] = 1.0;
- nu2->type = CU_2D;
BLI_addtail(&(cu->nurb), nu2);
}
@@ -1040,8 +1039,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
/* calc the right loc AND the right rot separately */
/* vec, tvec need 4 items */
- where_on_path(cu->textoncurve, ctime, vec, tvec);
- where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec);
+ where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL);
+ where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL);
VecMulf(vec, sizefac);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index dd8f44c71d5..43c4137e73e 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -214,6 +214,11 @@ bGPdata *gpencil_data_addnew (char name[])
/* initial settings */
gpd->flag = (GP_DATA_DISPINFO|GP_DATA_EXPAND);
+ /* for now, stick to view is also enabled by default
+ * since this is more useful...
+ */
+ gpd->flag |= GP_DATA_VIEWALIGN;
+
return gpd;
}
@@ -308,7 +313,7 @@ bGPdata *gpencil_data_duplicate (bGPdata *src)
void gpencil_frame_delete_laststroke (bGPDlayer *gpl, bGPDframe *gpf)
{
bGPDstroke *gps= (gpf) ? gpf->strokes.last : NULL;
- int cfra = 1; // XXX FIXME!!!
+ int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */
/* error checking */
if (ELEM(NULL, gpf, gps))
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 6fffbd794ef..6bb47bc0f0f 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -142,6 +142,16 @@ Group *add_group(char *name)
return group;
}
+Group *copy_group(Group *group)
+{
+ Group *groupn;
+
+ groupn= MEM_dupallocN(group);
+ BLI_duplicatelist(&groupn->gobject, &group->gobject);
+
+ return groupn;
+}
+
/* external */
void add_to_group(Group *group, Object *ob)
{
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index eb8872c43a5..cdb175ed661 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -38,6 +38,11 @@
#include <time.h>
+#ifdef _WIN32
+#define open _open
+#define close _close
+#endif
+
#include "MEM_guardedalloc.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index fc5213d5532..956a5851827 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -43,7 +43,7 @@
#include <windows.h>
static LARGE_INTEGER _itstart, _itend;
static LARGE_INTEGER ifreq;
-void itstart(void)
+static void itstart(void)
{
static int first = 1;
if(first) {
@@ -52,7 +52,7 @@ void itstart(void)
}
QueryPerformanceCounter(&_itstart);
}
-void itend(void)
+static void itend(void)
{
QueryPerformanceCounter(&_itend);
}
@@ -74,7 +74,7 @@ double itval()
{
gettimeofday(&_itstart, &itz);
}
-void itend(void)
+static void itend(void)
{
gettimeofday(&_itend,&itz);
}
@@ -155,7 +155,7 @@ DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vec
/* printf vector[3] on console: for debug output */
-void print_fvector(float m3[3])
+static void print_fvector(float m3[3])
{
printf("%f\n%f\n%f\n\n",m3[0],m3[1],m3[2]);
}
@@ -297,7 +297,7 @@ DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], f
// 3x3 matrix
///////////////////////////
/* printf 3x3 matrix on console: for debug output */
-void print_fmatrix(float m3[3][3])
+static void print_fmatrix(float m3[3][3])
{
printf("%f\t%f\t%f\n",m3[0][0],m3[0][1],m3[0][2]);
printf("%f\t%f\t%f\n",m3[1][0],m3[1][1],m3[1][2]);
@@ -496,7 +496,7 @@ DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float fro
// SPARSE SYMMETRIC big matrix with 3x3 matrix entries
///////////////////////////
/* printf a big matrix on console: for debug output */
-void print_bfmatrix(fmatrix3x3 *m3)
+static void print_bfmatrix(fmatrix3x3 *m3)
{
unsigned int i = 0;
@@ -887,7 +887,7 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
}
}
-int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
+static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
{
// Solves for unknown X in equation AX=B
unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
@@ -970,7 +970,7 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
}
/*
// version 1.3
-int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
+static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
{
unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0;
@@ -1038,7 +1038,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
}
*/
// version 1.4
-int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI)
+static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI)
{
unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0;
@@ -1183,7 +1183,8 @@ DO_INLINE void dfdx_spring(float to[3][3], float dir[3],float length,float L,fl
//return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k;
mul_fvectorT_fvector(to, dir, dir);
sub_fmatrix_fmatrix(to, I, to);
- mul_fmatrix_S(to, (((L/length)> 1.0f) ? (1.0f): (L/length)));
+
+ mul_fmatrix_S(to, (L/length));
sub_fmatrix_fmatrix(to, to, I);
mul_fmatrix_S(to, -k);
}
@@ -1218,6 +1219,8 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
float scaling = 0.0;
+
+ int no_compress = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
VECCOPY(s->f, nullf);
cp_fmatrix(s->dfdx, nulldfdx);
@@ -1254,7 +1257,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
// calculate force of structural + shear springs
if((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR))
{
- if(length > L) // only on elonglation
+ if(length > L || no_compress)
{
s->flags |= CLOTH_SPRING_FLAG_NEEDED;
@@ -1388,11 +1391,89 @@ static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n)
n[2]= n1[0]*n2[1]-n1[1]*n2[0];
}
-float calculateVertexWindForce(float wind[3], float vertexnormal[3])
+static float calculateVertexWindForce(float wind[3], float vertexnormal[3])
{
return (INPR(wind, vertexnormal));
}
+typedef struct HairGridVert {
+ float velocity[3];
+ float density;
+} HairGridVert;
+/* Smoothing of hair velocities:
+ * adapted from
+ Volumetric Methods for Simulation and Rendering of Hair
+ by Lena Petrovic, Mark Henne and John Anderson
+ * Pixar Technical Memo #06-08, Pixar Animation Studios
+ */
+static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX, lfVector *lV, int numverts)
+{
+ /* TODO: this is an initial implementation and should be made much better in due time */
+
+ /* 10x10x10 grid gives nice initial results */
+ HairGridVert grid[10][10][10];
+ float gmin[3], gmax[3], density;
+ int v = 0;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ lfVector temp;
+
+ INIT_MINMAX(gmin, gmax);
+
+ for(i = 0; i < numverts; i++)
+ DO_MINMAX(lX[i], gmin, gmax);
+
+ /* initialize grid */
+ for(i = 0; i < 10; i++) {
+ for(j = 0; j < 10; j++) {
+ for(k = 0; k < 10; k++) {
+ grid[i][j][k].velocity[0] = 0.0f;
+ grid[i][j][k].velocity[1] = 0.0f;
+ grid[i][j][k].velocity[2] = 0.0f;
+ grid[i][j][k].density = 0.0f;
+ }
+ }
+ }
+
+ /* gather velocities & density */
+ for(v = 0; v < numverts; v++) {
+ i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f );
+ j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f );
+ k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f );
+
+ grid[i][j][k].velocity[0] += lV[v][0];
+ grid[i][j][k].velocity[1] += lV[v][1];
+ grid[i][j][k].velocity[2] += lV[v][2];
+ grid[i][j][k].density += 1.0f;
+ }
+
+ /* divide velocity with density */
+ for(i = 0; i < 10; i++) {
+ for(j = 0; j < 10; j++) {
+ for(k = 0; k < 10; k++) {
+ density = grid[i][j][k].density;
+ if(density > 0.0f) {
+ grid[i][j][k].velocity[0] /= density;
+ grid[i][j][k].velocity[1] /= density;
+ grid[i][j][k].velocity[2] /= density;
+ }
+ }
+ }
+ }
+
+ /* calculate forces */
+ for(v = 0; v < numverts; v++) {
+ i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f );
+ j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f );
+ k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f );
+
+ /* 2.0f is an experimental value that seems to give good results */
+ lF[v][0] += 2.0f * smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
+ lF[v][1] += 2.0f * smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
+ lF[v][2] += 2.0f * smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]);
+ }
+}
static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
{
/* Collect forces and derivatives: F,dFdX,dFdV */
@@ -1416,6 +1497,9 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
init_lfvector(lF, gravity, numverts);
+ if(clmd->sim_parms->velocity_smooth > 0.0f)
+ hair_velocity_smoothing(clmd->sim_parms->velocity_smooth, lF, lX, lV, numverts);
+
/* multiply lF with mass matrix
// force = mass * acceleration (in this case: gravity)
*/
@@ -1511,7 +1595,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
// printf("\n");
}
-void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *M, fmatrix3x3 *bigI)
+static void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *M, fmatrix3x3 *bigI)
{
unsigned int numverts = dFdV[0].vcount;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 2f0e0931588..62f44d92d25 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -820,7 +820,7 @@ static char *particle_adrcodes_to_paths (int adrcode, int *array_index)
* - array_index - index in property's array (if applicable) to use
* - return - the allocated path...
*/
-char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index)
+static char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index)
{
DynStr *path= BLI_dynstr_new();
char *propname=NULL, *rpath=NULL;
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 4ba1c46d0c3..6d22b170e08 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -267,66 +267,91 @@ void sort_keys(Key *key)
/**************** do the key ****************/
+void key_curve_position_weights(float t, float *data, int type)
+{
+ float t2, t3, fc;
+
+ if(type==KEY_LINEAR) {
+ data[0]= 0.0f;
+ data[1]= -t + 1.0f;
+ data[2]= t;
+ data[3]= 0.0f;
+ }
+ else if(type==KEY_CARDINAL) {
+ t2= t*t;
+ t3= t2*t;
+ fc= 0.71f;
+
+ data[0]= -fc*t3 + 2.0f*fc*t2 - fc*t;
+ data[1]= (2.0f-fc)*t3 + (fc-3.0f)*t2 + 1.0f;
+ data[2]= (fc-2.0f)*t3 + (3.0f-2.0f*fc)*t2 + fc*t;
+ data[3]= fc*t3 - fc*t2;
+ }
+ else if(type==KEY_BSPLINE) {
+ t2= t*t;
+ t3= t2*t;
+
+ data[0]= -0.16666666f*t3 + 0.5f*t2 - 0.5f*t + 0.16666666f;
+ data[1]= 0.5f*t3 - t2 + 0.6666666f;
+ data[2]= -0.5f*t3 + 0.5f*t2 + 0.5f*t + 0.16666666f;
+ data[3]= 0.16666666f*t3;
+ }
+}
-void set_four_ipo(float d, float *data, int type)
+/* first derivative */
+void key_curve_tangent_weights(float t, float *data, int type)
{
- float d2, d3, fc;
+ float t2, fc;
if(type==KEY_LINEAR) {
data[0]= 0.0f;
- data[1]= 1.0f-d;
- data[2]= d;
+ data[1]= -1.0f;
+ data[2]= 1.0f;
data[3]= 0.0f;
}
- else {
- d2= d*d;
- d3= d2*d;
+ else if(type==KEY_CARDINAL) {
+ t2= t*t;
+ fc= 0.71f;
- if(type==KEY_CARDINAL) {
-
- fc= 0.71f;
-
- data[0]= -fc*d3 +2.0f*fc*d2 -fc*d;
- data[1]= (2.0f-fc)*d3 +(fc-3.0f)*d2 +1.0f;
- data[2]= (fc-2.0f)*d3 +(3.0f-2.0f*fc)*d2 +fc*d;
- data[3]= fc*d3 -fc*d2;
- }
- else if(type==KEY_BSPLINE) {
+ data[0]= -3.0f*fc*t2 +4.0f*fc*t - fc;
+ data[1]= 3.0f*(2.0f-fc)*t2 +2.0f*(fc-3.0f)*t;
+ data[2]= 3.0f*(fc-2.0f)*t2 +2.0f*(3.0f-2.0f*fc)*t + fc;
+ data[3]= 3.0f*fc*t2 -2.0f*fc*t;
+ }
+ else if(type==KEY_BSPLINE) {
+ t2= t*t;
- data[0]= -0.16666666f*d3 +0.5f*d2 -0.5f*d +0.16666666f;
- data[1]= 0.5f*d3 -d2 +0.6666666f;
- data[2]= -0.5f*d3 +0.5f*d2 +0.5f*d +0.16666666f;
- data[3]= 0.16666666f*d3 ;
- }
+ data[0]= -0.5f*t2 + t - 0.5f;
+ data[1]= 1.5f*t2 - 2.0f*t;
+ data[2]= -1.5f*t2 + t + 0.5f;
+ data[3]= 0.5f*t2;
}
}
-void set_afgeleide_four_ipo(float d, float *data, int type)
+/* second derivative */
+void key_curve_normal_weights(float t, float *data, int type)
{
- float d2, fc;
+ float fc;
if(type==KEY_LINEAR) {
-
+ data[0]= 0.0f;
+ data[1]= 0.0f;
+ data[2]= 0.0f;
+ data[3]= 0.0f;
}
- else {
- d2= d*d;
+ else if(type==KEY_CARDINAL) {
+ fc= 0.71f;
- if(type==KEY_CARDINAL) {
-
- fc= 0.71f;
-
- data[0]= -3.0f*fc*d2 +4.0f*fc*d -fc;
- data[1]= 3.0f*(2.0f-fc)*d2 +2.0f*(fc-3.0f)*d;
- data[2]= 3.0f*(fc-2.0f)*d2 +2.0f*(3.0f-2.0f*fc)*d +fc;
- data[3]= 3.0f*fc*d2 -2.0f*fc*d;
- }
- else if(type==KEY_BSPLINE) {
-
- data[0]= -0.16666666f*3.0f*d2 +d -0.5f;
- data[1]= 1.5f*d2 -2.0f*d;
- data[2]= -1.5f*d2 +d +0.5f;
- data[3]= 0.16666666f*3.0f*d2 ;
- }
+ data[0]= -6.0f*fc*t + 4.0f*fc;
+ data[1]= 6.0f*(2.0f-fc)*t + 2.0f*(fc-3.0f);
+ data[2]= 6.0f*(fc-2.0f)*t + 2.0f*(3.0f-2.0f*fc);
+ data[3]= 6.0f*fc*t - 2.0f*fc;
+ }
+ else if(type==KEY_BSPLINE) {
+ data[0]= -1.0f*t + 1.0f;
+ data[1]= 3.0f*t - 2.0f;
+ data[2]= -3.0f*t + 1.0f;
+ data[3]= 1.0f*t;
}
}
@@ -437,10 +462,10 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl)
/* interpolation */
- set_four_ipo(d, t, k[1]->type);
+ key_curve_position_weights(d, t, k[1]->type);
if(k[1]->type != k[2]->type) {
- set_four_ipo(d, fval, k[2]->type);
+ key_curve_position_weights(d, fval, k[2]->type);
temp= 1.0f-d;
t[0]= temp*t[0]+ d*fval[0];
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 70d76d25e93..d58f8447d28 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -365,7 +365,7 @@ void calc_latt_deform(Object *ob, float *co, float weight)
u= (vec[0]-lt->fu)/lt->du;
ui= (int)floor(u);
u -= ui;
- set_four_ipo(u, tu, lt->typeu);
+ key_curve_position_weights(u, tu, lt->typeu);
}
else {
tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
@@ -376,7 +376,7 @@ void calc_latt_deform(Object *ob, float *co, float weight)
v= (vec[1]-lt->fv)/lt->dv;
vi= (int)floor(v);
v -= vi;
- set_four_ipo(v, tv, lt->typev);
+ key_curve_position_weights(v, tv, lt->typev);
}
else {
tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
@@ -387,7 +387,7 @@ void calc_latt_deform(Object *ob, float *co, float weight)
w= (vec[2]-lt->fw)/lt->dw;
wi= (int)floor(w);
w -= wi;
- set_four_ipo(w, tw, lt->typew);
+ key_curve_position_weights(w, tw, lt->typew);
}
else {
tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
@@ -473,7 +473,7 @@ static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc
}
/* this makes sure we can extend for non-cyclic. *vec needs 4 items! */
-static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir) /* returns OK */
+static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
{
Curve *cu= ob->data;
BevList *bl;
@@ -491,21 +491,25 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir)
else ctime1= ctime;
/* vec needs 4 items */
- if(where_on_path(ob, ctime1, vec, dir)) {
+ if(where_on_path(ob, ctime1, vec, dir, quat, radius)) {
if(cycl==0) {
Path *path= cu->path;
float dvec[3];
if(ctime < 0.0) {
- VecSubf(dvec, path->data+4, path->data);
+ VecSubf(dvec, path->data[1].vec, path->data[0].vec);
VecMulf(dvec, ctime*(float)path->len);
VECADD(vec, vec, dvec);
+ if(quat) QUATCOPY(quat, path->data[0].quat);
+ if(radius) *radius= path->data[0].radius;
}
else if(ctime > 1.0) {
- VecSubf(dvec, path->data+4*path->len-4, path->data+4*path->len-8);
+ VecSubf(dvec, path->data[path->len-1].vec, path->data[path->len-2].vec);
VecMulf(dvec, (ctime-1.0)*(float)path->len);
VECADD(vec, vec, dvec);
+ if(quat) QUATCOPY(quat, path->data[path->len-1].quat);
+ if(radius) *radius= path->data[path->len-1].radius;
}
}
return 1;
@@ -521,7 +525,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir)
static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
{
Curve *cu= par->data;
- float fac, loc[4], dir[3], cent[3];
+ float fac, loc[4], dir[3], cent[3], radius;
short upflag, index;
if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) {
@@ -576,7 +580,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
}
#endif // XXX old animation system
- if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
+ if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) { /* returns OK */
float q[4], mat[3][3], quat[4];
if(cd->no_rot_axis) /* set by caller */
@@ -596,7 +600,14 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
QuatMul(quat, q, quat);
}
QuatToMat3(quat, mat);
-
+
+ if(cu->flag & CU_PATH_RADIUS) {
+ float tmat[3][3], rmat[3][3];
+ Mat3Scale(tmat, radius);
+ Mat3MulMat3(rmat, mat, tmat);
+ Mat3CpyMat3(mat, rmat);
+ }
+
/* local rotation */
Mat3MulVecfl(mat, cent);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index c1654646a2b..eb9d578402d 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -119,6 +119,13 @@
#define MAX_IDPUP 60 /* was 24 */
+/* GS reads the memory pointed at in a specific ordering.
+ only use this definition, makes little and big endian systems
+ work fine, in conjunction with MAKE_ID */
+
+/* from blendef: */
+#define GS(a) (*((short *)(a)))
+
/* ************* general ************************ */
void id_lib_extern(ID *id)
@@ -148,6 +155,220 @@ void id_us_min(ID *id)
id->us--;
}
+int id_make_local(ID *id, int test)
+{
+ if(id->flag & LIB_INDIRECT)
+ return 0;
+
+ switch(GS(id->name)) {
+ case ID_SCE:
+ return 0; /* not implemented */
+ case ID_LI:
+ return 0; /* can't be linked */
+ case ID_OB:
+ if(!test) make_local_object((Object*)id);
+ return 1;
+ case ID_ME:
+ if(!test) {
+ make_local_mesh((Mesh*)id);
+ make_local_key(((Mesh*)id)->key);
+ }
+ return 1;
+ case ID_CU:
+ if(!test) {
+ make_local_curve((Curve*)id);
+ make_local_key(((Curve*)id)->key);
+ }
+ return 1;
+ case ID_MB:
+ if(!test) make_local_mball((MetaBall*)id);
+ return 1;
+ case ID_MA:
+ if(!test) make_local_material((Material*)id);
+ return 1;
+ case ID_TE:
+ if(!test) make_local_texture((Tex*)id);
+ return 1;
+ case ID_IM:
+ return 0; /* not implemented */
+ case ID_WV:
+ return 0; /* deprecated */
+ case ID_LT:
+ if(!test) {
+ make_local_lattice((Lattice*)id);
+ make_local_key(((Lattice*)id)->key);
+ }
+ return 1;
+ case ID_LA:
+ if(!test) make_local_lamp((Lamp*)id);
+ return 1;
+ case ID_CA:
+ if(!test) make_local_camera((Camera*)id);
+ return 1;
+ case ID_IP:
+ return 0; /* deprecated */
+ case ID_KE:
+ if(!test) make_local_key((Key*)id);
+ return 1;
+ case ID_WO:
+ if(!test) make_local_world((World*)id);
+ return 1;
+ case ID_SCR:
+ return 0; /* can't be linked */
+ case ID_VF:
+ return 0; /* not implemented */
+ case ID_TXT:
+ return 0; /* not implemented */
+ case ID_SCRIPT:
+ return 0; /* deprecated */
+ case ID_SO:
+ return 0; /* not implemented */
+ case ID_GR:
+ return 0; /* not implemented */
+ case ID_AR:
+ if(!test) make_local_armature((bArmature*)id);
+ return 1;
+ case ID_AC:
+ if(!test) make_local_action((bAction*)id);
+ return 1;
+ case ID_NT:
+ return 0; /* not implemented */
+ case ID_BR:
+ if(!test) make_local_brush((Brush*)id);
+ return 1;
+ case ID_PA:
+ if(!test) make_local_particlesettings((ParticleSettings*)id);
+ return 1;
+ case ID_WM:
+ return 0; /* can't be linked */
+ case ID_GD:
+ return 0; /* not implemented */
+ }
+
+ return 0;
+}
+
+int id_copy(ID *id, ID **newid, int test)
+{
+ if(!test) *newid= NULL;
+
+ /* conventions:
+ * - make shallow copy, only this ID block
+ * - id.us of the new ID is set to 1 */
+ switch(GS(id->name)) {
+ case ID_SCE:
+ return 0; /* can't be copied from here */
+ case ID_LI:
+ return 0; /* can't be copied from here */
+ case ID_OB:
+ if(!test) *newid= (ID*)copy_object((Object*)id);
+ return 1;
+ case ID_ME:
+ if(!test) *newid= (ID*)copy_mesh((Mesh*)id);
+ return 1;
+ case ID_CU:
+ if(!test) *newid= (ID*)copy_curve((Curve*)id);
+ return 1;
+ case ID_MB:
+ if(!test) *newid= (ID*)copy_mball((MetaBall*)id);
+ return 1;
+ case ID_MA:
+ if(!test) *newid= (ID*)copy_material((Material*)id);
+ return 1;
+ case ID_TE:
+ if(!test) *newid= (ID*)copy_texture((Tex*)id);
+ return 1;
+ case ID_IM:
+ return 0; /* not implemented */
+ case ID_WV:
+ return 0; /* deprecated */
+ case ID_LT:
+ if(!test) *newid= (ID*)copy_lattice((Lattice*)id);
+ return 1;
+ case ID_LA:
+ if(!test) *newid= (ID*)copy_lamp((Lamp*)id);
+ return 1;
+ case ID_CA:
+ if(!test) *newid= (ID*)copy_camera((Camera*)id);
+ return 1;
+ case ID_IP:
+ return 0; /* deprecated */
+ case ID_KE:
+ if(!test) *newid= (ID*)copy_key((Key*)id);
+ return 1;
+ case ID_WO:
+ if(!test) *newid= (ID*)copy_world((World*)id);
+ return 1;
+ case ID_SCR:
+ return 0; /* can't be copied from here */
+ case ID_VF:
+ return 0; /* not implemented */
+ case ID_TXT:
+ if(!test) *newid= (ID*)copy_text((Text*)id);
+ return 1;
+ case ID_SCRIPT:
+ return 0; /* deprecated */
+ case ID_SO:
+ return 0; /* not implemented */
+ case ID_GR:
+ if(!test) *newid= (ID*)copy_group((Group*)id);
+ return 1;
+ case ID_AR:
+ if(!test) *newid= (ID*)copy_armature((bArmature*)id);
+ return 1;
+ case ID_AC:
+ if(!test) *newid= (ID*)copy_action((bAction*)id);
+ return 1;
+ case ID_NT:
+ if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id, 0);
+ return 1;
+ case ID_BR:
+ if(!test) *newid= (ID*)copy_brush((Brush*)id);
+ return 1;
+ case ID_PA:
+ if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id);
+ return 1;
+ case ID_WM:
+ return 0; /* can't be copied from here */
+ case ID_GD:
+ return 0; /* not implemented */
+ }
+
+ return 0;
+}
+
+int id_unlink(ID *id, int test)
+{
+ Main *mainlib= G.main;
+ ListBase *lb;
+
+ switch(GS(id->name)) {
+ case ID_TXT:
+ if(test) return 1;
+ unlink_text(mainlib, (Text*)id);
+ break;
+ case ID_GR:
+ if(test) return 1;
+ unlink_group((Group*)id);
+ break;
+ case ID_OB:
+ if(test) return 1;
+ unlink_object(NULL, (Object*)id);
+ break;
+ }
+
+ if(id->us == 0) {
+ if(test) return 1;
+
+ lb= wich_libbase(mainlib, GS(id->name));
+ free_libblock(lb, id);
+
+ return 1;
+ }
+
+ return 0;
+}
+
ListBase *wich_libbase(Main *mainlib, short type)
{
switch( type ) {
@@ -234,6 +455,15 @@ void flag_all_listbases_ids(short flag, short value)
while(a--) flag_listbase_ids(lbarray[a], flag, value);
}
+void recalc_all_library_objects(Main *main)
+{
+ Object *ob;
+
+ /* flag for full recalc */
+ for(ob=main->object.first; ob; ob=ob->id.next)
+ if(ob->id.lib)
+ ob->recalc |= OB_RECALC;
+}
/* note: MAX_LIBARRAY define should match this code */
int set_listbasepointers(Main *main, ListBase **lb)
@@ -409,13 +639,6 @@ void *alloc_libblock(ListBase *lb, short type, const char *name)
return id;
}
-/* GS reads the memory pointed at in a specific ordering.
- only use this definition, makes little and big endian systems
- work fine, in conjunction with MAKE_ID */
-
-/* from blendef: */
-#define GS(a) (*((short *)(a)))
-
/* by spec, animdata is first item after ID */
/* we still read ->adt itself, to ensure compiler warns when it doesnt exist */
static void id_copy_animdata(ID *id)
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 53de570b55e..1667bd97102 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -159,9 +159,9 @@ void init_material(Material *ma)
ma->sss_radius[0]= 1.0f;
ma->sss_radius[1]= 1.0f;
ma->sss_radius[2]= 1.0f;
- ma->sss_col[0]= 0.8f;
- ma->sss_col[1]= 0.8f;
- ma->sss_col[2]= 0.8f;
+ ma->sss_col[0]= 1.0f;
+ ma->sss_col[1]= 1.0f;
+ ma->sss_col[2]= 1.0f;
ma->sss_error= 0.05f;
ma->sss_scale= 0.1f;
ma->sss_ior= 1.3f;
@@ -1031,15 +1031,15 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
}
break;
case MA_RAMP_DARK:
- tmp= fac*col[0];
- if(tmp < *r) *r= tmp;
- if(g) {
- tmp= fac*col[1];
- if(tmp < *g) *g= tmp;
- tmp= fac*col[2];
- if(tmp < *b) *b= tmp;
- }
- break;
+ tmp=col[0]+((1-col[0])*facm);
+ if(tmp < *r) *r= tmp;
+ if(g) {
+ tmp=col[1]+((1-col[1])*facm);
+ if(tmp < *g) *g= tmp;
+ tmp=col[2]+((1-col[2])*facm);
+ if(tmp < *b) *b= tmp;
+ }
+ break;
case MA_RAMP_LIGHT:
tmp= fac*col[0];
if(tmp > *r) *r= tmp;
@@ -1169,8 +1169,37 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
}
}
break;
- }
-
+ case MA_RAMP_SOFT:
+ if (g){
+ float scr, scg, scb;
+
+ /* first calculate non-fac based Screen mix */
+ scr = 1.0 - ((1.0 - col[0])) * (1.0 - *r);
+ scg = 1.0 - ((1.0 - col[1])) * (1.0 - *g);
+ scb = 1.0 - ((1.0 - col[2])) * (1.0 - *b);
+
+ *r = facm*(*r) + fac*(((1.0 - *r) * col[0] * (*r)) + (*r * scr));
+ *g = facm*(*g) + fac*(((1.0 - *g) * col[1] * (*g)) + (*g * scg));
+ *b = facm*(*b) + fac*(((1.0 - *b) * col[2] * (*b)) + (*b * scb));
+ }
+ break;
+ case MA_RAMP_LINEAR:
+ if (col[0] > 0.5)
+ *r = *r + fac*(2*(col[0]-0.5));
+ else
+ *r = *r + fac*(2*(col[0]) - 1);
+ if (g){
+ if (col[1] > 0.5)
+ *g = *g + fac*(2*(col[1]-0.5));
+ else
+ *g = *g + fac*(2*(col[1]) -1);
+ if (col[2] > 0.5)
+ *b = *b + fac*(2*(col[2]-0.5));
+ else
+ *b = *b + fac*(2*(col[2]) - 1);
+ }
+ break;
+ }
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 35e2989650a..18a88cdb36a 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1110,7 +1110,7 @@ void mesh_set_smooth_flag(Object *meshOb, int enableSmooth)
}
}
-// XXX do this in caller DAG_object_flush_update(scene, meshOb, OB_RECALC_DATA);
+// XXX do this in caller DAG_id_flush_update(&me->id, OB_RECALC_DATA);
}
void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float **faceNors_r)
@@ -1398,7 +1398,7 @@ void mesh_pmv_revert(Object *ob, Mesh *me)
MEM_freeN(me->pv->vert_map);
me->pv->vert_map= NULL;
-// XXX do this in caller DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+// XXX do this in caller DAG_id_flush_update(&me->id, OB_RECALC_DATA);
}
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 496cc2b8224..a4813eb0247 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -76,8 +76,8 @@
#include "BLI_editVert.h"
-#include "MTC_matrixops.h"
-#include "MTC_vectorops.h"
+
+
#include "BKE_main.h"
#include "BKE_anim.h"
@@ -218,7 +218,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tcmd->name, cmd->name, 32);
}
-CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CurveModifierData *cmd = (CurveModifierData *)md;
CustomDataMask dataMask = 0;
@@ -294,7 +294,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tlmd->name, lmd->name, 32);
}
-CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
{
LatticeModifierData *lmd = (LatticeModifierData *)md;
CustomDataMask dataMask = 0;
@@ -1111,7 +1111,7 @@ static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest, Sc
}
}
-float vertarray_size(MVert *mvert, int numVerts, int axis)
+static float vertarray_size(MVert *mvert, int numVerts, int axis)
{
int i;
float min_co, max_co;
@@ -1198,7 +1198,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if(amd->end_cap && amd->end_cap != ob)
end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
- MTC_Mat4One(offset);
+ Mat4One(offset);
indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm),
"indexmap");
@@ -1220,14 +1220,14 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
float result_mat[4][4];
if(ob)
- MTC_Mat4Invert(obinv, ob->obmat);
+ Mat4Invert(obinv, ob->obmat);
else
- MTC_Mat4One(obinv);
+ Mat4One(obinv);
- MTC_Mat4MulSerie(result_mat, offset,
+ Mat4MulSerie(result_mat, offset,
obinv, amd->offset_ob->obmat,
NULL, NULL, NULL, NULL, NULL);
- MTC_Mat4CpyMat4(offset, result_mat);
+ Mat4CpyMat4(offset, result_mat);
}
if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
@@ -1252,7 +1252,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
prescribed length */
if(amd->fit_type == MOD_ARR_FITLENGTH
|| amd->fit_type == MOD_ARR_FITCURVE) {
- float dist = sqrt(MTC_dot3Float(offset[3], offset[3]));
+ float dist = sqrt(Inpf(offset[3], offset[3]));
if(dist > 1e-6f)
/* this gives length = first copy start to last copy end
@@ -1285,11 +1285,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces, 0, 0);
/* calculate the offset matrix of the final copy (for merging) */
- MTC_Mat4One(final_offset);
+ Mat4One(final_offset);
for(j=0; j < count - 1; j++) {
- MTC_Mat4MulMat4(tmp_mat, final_offset, offset);
- MTC_Mat4CpyMat4(final_offset, tmp_mat);
+ Mat4MulMat4(tmp_mat, final_offset, offset);
+ Mat4CpyMat4(final_offset, tmp_mat);
}
numVerts = numEdges = numFaces = 0;
@@ -1325,7 +1325,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
float tmp_co[3];
VECCOPY(tmp_co, mv->co);
- MTC_Mat4MulVecfl(offset, tmp_co);
+ Mat4MulVecfl(offset, tmp_co);
for(j = 0; j < maxVerts; j++) {
/* if vertex already merged, don't use it */
@@ -1340,7 +1340,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if(amd->flags & MOD_ARR_MERGEFINAL) {
VECCOPY(tmp_co, inMV->co);
inMV = &src_mvert[i];
- MTC_Mat4MulVecfl(final_offset, tmp_co);
+ Mat4MulVecfl(final_offset, tmp_co);
if(VecLenCompare(tmp_co, inMV->co, amd->merge_dist))
indexMap[i].merge_final = 1;
}
@@ -1358,7 +1358,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
*mv2 = *mv;
numVerts++;
- MTC_Mat4MulVecfl(offset, co);
+ Mat4MulVecfl(offset, co);
VECCOPY(mv2->co, co);
}
} else if(indexMap[i].merge != i && indexMap[i].merge_final) {
@@ -1789,7 +1789,7 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, S
/* finds the best possible flipped name. For renaming; check for unique names afterwards */
/* if strip_number: removes number extensions */
-void vertgroup_flip_name (char *name, int strip_number)
+static void vertgroup_flip_name (char *name, int strip_number)
{
int len;
char prefix[128]={""}; /* The part before the facing */
@@ -2326,7 +2326,7 @@ DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd)
VECCOPY(etags[ml->e].fno, no);
etags[ml->e].has_fno = 1;
} else if (!etags[ml->e].tag) {
- edge_angle_cos = MTC_dot3Float(etags[ml->e].fno, no);
+ edge_angle_cos = INPR(etags[ml->e].fno, no);
if (edge_angle_cos < threshold) {
etags[ml->e].tag = 1;
}
@@ -2593,7 +2593,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
}
-CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
{
BevelModifierData *bmd = (BevelModifierData *)md;
CustomDataMask dataMask = 0;
@@ -2673,7 +2673,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
}
-CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
{
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
CustomDataMask dataMask = 0;
@@ -3017,7 +3017,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
tumd->aspecty = umd->aspecty;
}
-CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = 0;
@@ -3243,11 +3243,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
/* find the projector which the face points at most directly
* (projector normal with largest dot product is best)
*/
- best_dot = MTC_dot3Float(projectors[0].normal, face_no);
+ best_dot = Inpf(projectors[0].normal, face_no);
best_projector = &projectors[0];
for(j = 1; j < num_projectors; ++j) {
- float tmp_dot = MTC_dot3Float(projectors[j].normal,
+ float tmp_dot = Inpf(projectors[j].normal,
face_no);
if(tmp_dot > best_dot) {
best_dot = tmp_dot;
@@ -3470,7 +3470,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
}
-int smoothModifier_isDisabled(ModifierData *md)
+static int smoothModifier_isDisabled(ModifierData *md)
{
SmoothModifierData *smd = (SmoothModifierData*) md;
short flag;
@@ -3483,7 +3483,7 @@ int smoothModifier_isDisabled(ModifierData *md)
return 0;
}
-CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
CustomDataMask dataMask = 0;
@@ -3700,7 +3700,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
}
-int castModifier_isDisabled(ModifierData *md)
+static int castModifier_isDisabled(ModifierData *md)
{
CastModifierData *cmd = (CastModifierData*) md;
short flag;
@@ -3712,7 +3712,7 @@ int castModifier_isDisabled(ModifierData *md)
return 0;
}
-CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CastModifierData *cmd = (CastModifierData *)md;
CustomDataMask dataMask = 0;
@@ -4343,7 +4343,7 @@ static void waveModifier_updateDepgraph(
}
}
-CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
{
WaveModifierData *wmd = (WaveModifierData *)md;
CustomDataMask dataMask = 0;
@@ -4679,7 +4679,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
}
-CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = 0;
@@ -4794,7 +4794,7 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(thmd->subtarget, hmd->subtarget, 32);
}
-CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
{
HookModifierData *hmd = (HookModifierData *)md;
CustomDataMask dataMask = 0;
@@ -5139,7 +5139,7 @@ static void clothModifier_updateDepgraph(
}
}
-CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = 0;
@@ -5563,7 +5563,7 @@ static DerivedMesh *booleanModifier_applyModifier(
return derivedData;
}
-CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
@@ -5611,7 +5611,7 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ
tpsmd->psys = psmd->psys;
}
-CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
{
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
CustomDataMask dataMask = 0;
@@ -5888,10 +5888,8 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){
float ran = 0.0f;
if(pimd->random_position != 0.0f) {
- /* just use some static collection of random numbers */
- /* TODO: use something else that's unique to each instanced object */
- pa = psys->particles + (i/totvert)%totpart;
- ran = pimd->random_position * 0.5 * (1.0f + pa->r_ave[0]);
+ BLI_srandom(psys->seed + (i/totvert)%totpart);
+ ran = pimd->random_position * BLI_frand();
}
if(pimd->flag & eParticleInstanceFlag_KeepShape) {
@@ -6027,7 +6025,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md)
{
return 1;
}
-CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
{
ExplodeModifierData *emd= (ExplodeModifierData*) md;
CustomDataMask dataMask = 0;
@@ -6943,7 +6941,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
tmmd->object = mmd->object;
}
-CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
CustomDataMask dataMask = 0;
@@ -7322,7 +7320,7 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
tsmd->subsurfLevels = smd->subsurfLevels;
}
-CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
CustomDataMask dataMask = 0;
@@ -8333,7 +8331,7 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek)
return i;
}
-int modifiers_usesPointCache(Object *ob)
+static int modifiers_usesPointCache(Object *ob)
{
ModifierData *md = ob->modifiers.first;
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 3cf1785f3ef..b502c21188f 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -67,9 +67,6 @@
#include "BLI_editVert.h"
-#include "MTC_matrixops.h"
-#include "MTC_vectorops.h"
-
#include "BKE_main.h"
#include "BKE_anim.h"
#include "BKE_bmesh.h"
@@ -230,8 +227,136 @@ BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, BMEditMesh *existing)
return em;
}
-float vertarray_size(MVert *mvert, int numVerts, int axis);
+static float vertarray_size(MVert *mvert, int numVerts, int axis)
+{
+ int i;
+ float min_co, max_co;
+
+ /* if there are no vertices, width is 0 */
+ if(numVerts == 0) return 0;
+
+ /* find the minimum and maximum coordinates on the desired axis */
+ min_co = max_co = mvert->co[axis];
+ ++mvert;
+ for(i = 1; i < numVerts; ++i, ++mvert) {
+ if(mvert->co[axis] < min_co) min_co = mvert->co[axis];
+ if(mvert->co[axis] > max_co) max_co = mvert->co[axis];
+ }
+
+ return max_co - min_co;
+}
+
+/* finds the best possible flipped name. For renaming; check for unique names afterwards */
+/* if strip_number: removes number extensions */
+static void vertgroup_flip_name (char *name, int strip_number)
+{
+ int len;
+ char prefix[128]={""}; /* The part before the facing */
+ char suffix[128]={""}; /* The part after the facing */
+ char replace[128]={""}; /* The replacement string */
+ char number[128]={""}; /* The number extension string */
+ char *index=NULL;
+
+ len= strlen(name);
+ if(len<3) return; // we don't do names like .R or .L
+
+ /* We first check the case with a .### extension, let's find the last period */
+ if(isdigit(name[len-1])) {
+ index= strrchr(name, '.'); // last occurrance
+ if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
+ if(strip_number==0)
+ strcpy(number, index);
+ *index= 0;
+ len= strlen(name);
+ }
+ }
+
+ strcpy (prefix, name);
+
+#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
+
+ /* first case; separator . - _ with extensions r R l L */
+ if( IS_SEPARATOR(name[len-2]) ) {
+ switch(name[len-1]) {
+ case 'l':
+ prefix[len-1]= 0;
+ strcpy(replace, "r");
+ break;
+ case 'r':
+ prefix[len-1]= 0;
+ strcpy(replace, "l");
+ break;
+ case 'L':
+ prefix[len-1]= 0;
+ strcpy(replace, "R");
+ break;
+ case 'R':
+ prefix[len-1]= 0;
+ strcpy(replace, "L");
+ break;
+ }
+ }
+ /* case; beginning with r R l L , with separator after it */
+ else if( IS_SEPARATOR(name[1]) ) {
+ switch(name[0]) {
+ case 'l':
+ strcpy(replace, "r");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ case 'r':
+ strcpy(replace, "l");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ case 'L':
+ strcpy(replace, "R");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ case 'R':
+ strcpy(replace, "L");
+ strcpy(suffix, name+1);
+ prefix[0]= 0;
+ break;
+ }
+ }
+ else if(len > 5) {
+ /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
+ index = BLI_strcasestr(prefix, "right");
+ if (index==prefix || index==prefix+len-5) {
+ if(index[0]=='r')
+ strcpy (replace, "left");
+ else {
+ if(index[1]=='I')
+ strcpy (replace, "LEFT");
+ else
+ strcpy (replace, "Left");
+ }
+ *index= 0;
+ strcpy (suffix, index+5);
+ }
+ else {
+ index = BLI_strcasestr(prefix, "left");
+ if (index==prefix || index==prefix+len-4) {
+ if(index[0]=='l')
+ strcpy (replace, "right");
+ else {
+ if(index[1]=='E')
+ strcpy (replace, "RIGHT");
+ else
+ strcpy (replace, "Right");
+ }
+ *index= 0;
+ strcpy (suffix, index+4);
+ }
+ }
+ }
+
+#undef IS_SEPARATOR
+ sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
+}
typedef struct IndexMapEntry {
/* the new vert index that this old vert index maps to */
@@ -296,7 +421,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if(amd->end_cap && amd->end_cap != ob)
end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
- MTC_Mat4One(offset);
+ Mat4One(offset);
src_mvert = cddm->getVertArray(dm);
maxVerts = cddm->getNumVerts(dm);
@@ -314,14 +439,14 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
float result_mat[4][4];
if(ob)
- MTC_Mat4Invert(obinv, ob->obmat);
+ Mat4Invert(obinv, ob->obmat);
else
- MTC_Mat4One(obinv);
+ Mat4One(obinv);
- MTC_Mat4MulSerie(result_mat, offset,
+ Mat4MulSerie(result_mat, offset,
obinv, amd->offset_ob->obmat,
NULL, NULL, NULL, NULL, NULL);
- MTC_Mat4CpyMat4(offset, result_mat);
+ Mat4CpyMat4(offset, result_mat);
}
if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
@@ -347,7 +472,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if(amd->fit_type == MOD_ARR_FITLENGTH
|| amd->fit_type == MOD_ARR_FITCURVE)
{
- float dist = sqrt(MTC_dot3Float(offset[3], offset[3]));
+ float dist = sqrt(INPR(offset[3], offset[3]));
if(dist > 1e-6f)
/* this gives length = first copy start to last copy end
@@ -379,11 +504,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
}
/* calculate the offset matrix of the final copy (for merging) */
- MTC_Mat4One(final_offset);
+ Mat4One(final_offset);
for(j=0; j < count - 1; j++) {
- MTC_Mat4MulMat4(tmp_mat, final_offset, offset);
- MTC_Mat4CpyMat4(final_offset, tmp_mat);
+ Mat4MulMat4(tmp_mat, final_offset, offset);
+ Mat4CpyMat4(final_offset, tmp_mat);
}
BMO_Init_Op(&weldop, "weldverts");
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 2555bc6de27..f38b36d47b3 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -83,7 +83,7 @@ int multiresModifier_switch_level(Object *ob, const int distance)
mmd->lvl += distance;
if(mmd->lvl < 1) mmd->lvl = 1;
else if(mmd->lvl > mmd->totlvl) mmd->lvl = mmd->totlvl;
- /* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ /* XXX: DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
object_handle_update(ob);*/
return 1;
}
@@ -596,7 +596,7 @@ static void find_displacer_edges(MultiresDisplacer *d, DerivedMesh *dm, Displace
}
/* Returns in out the corners [0-3] that use v1 and v2 */
-void find_face_corners(MFace *f, int v1, int v2, int out[2])
+static void find_face_corners(MFace *f, int v1, int v2, int out[2])
{
int i, end = f->v4 ? 4 : 3;
@@ -1259,7 +1259,7 @@ struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, i
***************************/
/* Does not actually free lvl itself */
-void multires_free_level(MultiresLevel *lvl)
+static void multires_free_level(MultiresLevel *lvl)
{
if(lvl) {
if(lvl->faces) MEM_freeN(lvl->faces);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 480c79fbc1a..83ee71bfe40 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1048,7 +1048,7 @@ short BKE_nlastrip_within_bounds (NlaStrip *strip, float min, float max)
/* Is the given NLA-strip the first one to occur for the given AnimData block */
// TODO: make this an api method if necesary, but need to add prefix first
-short nlastrip_is_first (AnimData *adt, NlaStrip *strip)
+static short nlastrip_is_first (AnimData *adt, NlaStrip *strip)
{
NlaTrack *nlt;
NlaStrip *ns;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index bd6919dc115..90ea53d4364 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -2597,7 +2597,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
if(outsocket_exists(lnode->new_node, lsock->new_sock)) {
lsock->new_sock->ns.data= lsock->ns.data;
lsock->ns.data= NULL;
- lsock->new_sock= NULL;
+ lsock->new_sock= NULL;
}
}
}
@@ -2932,6 +2932,7 @@ static void registerCompositNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &cmp_node_viewer);
nodeRegisterType(ntypelist, &cmp_node_splitviewer);
nodeRegisterType(ntypelist, &cmp_node_output_file);
+ nodeRegisterType(ntypelist, &cmp_node_view_levels);
nodeRegisterType(ntypelist, &cmp_node_curve_rgb);
nodeRegisterType(ntypelist, &cmp_node_mix_rgb);
@@ -2971,7 +2972,9 @@ static void registerCompositNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &cmp_node_premulkey);
nodeRegisterType(ntypelist, &cmp_node_diff_matte);
- nodeRegisterType(ntypelist, &cmp_node_chroma);
+ nodeRegisterType(ntypelist, &cmp_node_distance_matte);
+ nodeRegisterType(ntypelist, &cmp_node_chroma_matte);
+ nodeRegisterType(ntypelist, &cmp_node_color_matte);
nodeRegisterType(ntypelist, &cmp_node_channel_matte);
nodeRegisterType(ntypelist, &cmp_node_color_spill);
nodeRegisterType(ntypelist, &cmp_node_luma_matte);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index cdcd90b6ebf..54c9293fd57 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -102,13 +102,13 @@
#include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_property.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_sculpt.h"
#include "BKE_softbody.h"
#include "LBM_fluidsim.h"
@@ -285,6 +285,7 @@ void free_object(Object *ob)
if(ob->adt) BKE_free_animdata((ID *)ob);
if(ob->poselib) ob->poselib->id.us--;
if(ob->dup_group) ob->dup_group->id.us--;
+ if(ob->gpd) ob->gpd->id.us--;
if(ob->defbase.first)
BLI_freelistN(&ob->defbase);
if(ob->pose)
@@ -481,15 +482,15 @@ void unlink_object(Scene *scene, Object *ob)
if(tpsys->part->dup_ob==ob)
tpsys->part->dup_ob= NULL;
- if(tpsys->part->flag&PART_STICKY) {
+ if(tpsys->part->phystype==PART_PHYS_BOIDS) {
ParticleData *pa;
+ BoidParticle *bpa;
int p;
for(p=0,pa=tpsys->particles; p<tpsys->totpart; p++,pa++) {
- if(pa->stick_ob==ob) {
- pa->stick_ob= 0;
- pa->flag &= ~PARS_STICKY;
- }
+ bpa = pa->boid;
+ if(bpa->ground == ob)
+ bpa->ground = NULL;
}
}
if(tpsys->part->boids) {
@@ -1082,34 +1083,44 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
{
ParticleSystem *psysn;
ParticleData *pa;
- int a;
+ int p;
psysn= MEM_dupallocN(psys);
psysn->particles= MEM_dupallocN(psys->particles);
psysn->child= MEM_dupallocN(psys->child);
- if(psysn->particles->keys)
- psysn->particles->keys = MEM_dupallocN(psys->particles->keys);
- for(a=0, pa=psysn->particles; a<psysn->totpart; a++, pa++) {
- if(pa->hair)
- pa->hair= MEM_dupallocN(pa->hair);
- if(a)
- pa->keys= (pa-1)->keys + (pa-1)->totkey;
+ if(psys->part->type == PART_HAIR) {
+ for(p=0, pa=psysn->particles; p<psysn->totpart; p++, pa++)
+ pa->hair = MEM_dupallocN(pa->hair);
}
- if(psys->soft) {
- psysn->soft= copy_softbody(psys->soft);
- psysn->soft->particles = psysn;
+ if(psysn->particles->keys || psysn->particles->boid) {
+ ParticleKey *key = psysn->particles->keys;
+ BoidParticle *boid = psysn->particles->boid;
+
+ if(key)
+ key = MEM_dupallocN(key);
+
+ if(boid)
+ boid = MEM_dupallocN(boid);
+
+ for(p=0, pa=psysn->particles; p<psysn->totpart; p++, pa++) {
+ if(boid)
+ pa->boid = boid++;
+ if(key) {
+ pa->keys = key;
+ key += pa->totkey;
+ }
+ }
}
- if(psys->particles->boid) {
- psysn->particles->boid = MEM_dupallocN(psys->particles->boid);
- for(a=1, pa=psysn->particles+1; a<psysn->totpart; a++, pa++)
- pa->boid = (pa-1)->boid + 1;
+ if(psys->clmd) {
+ ClothModifierData *nclmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
+ modifier_copyData((ModifierData*)psys->clmd, (ModifierData*)nclmd);
+ psys->hair_in_dm = psys->hair_out_dm = NULL;
}
- if(psys->targets.first)
- BLI_duplicatelist(&psysn->targets, &psys->targets);
+ BLI_duplicatelist(&psysn->targets, &psys->targets);
psysn->pathcache= NULL;
psysn->childcache= NULL;
@@ -1396,7 +1407,7 @@ int object_data_is_libdata(Object *ob)
/* *************** PROXY **************** */
/* when you make proxy, ensure the exposed layers are extern */
-void armature_set_id_extern(Object *ob)
+static void armature_set_id_extern(Object *ob)
{
bArmature *arm= ob->data;
bPoseChannel *pchan;
@@ -1636,7 +1647,7 @@ int enable_cu_speed= 1;
static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
{
Curve *cu;
- float q[4], vec[4], dir[3], quat[4], x1, ctime;
+ float q[4], vec[4], dir[3], quat[4], radius, x1, ctime;
float timeoffs = 0.0, sf_orig = 0.0;
Mat4One(mat);
@@ -1684,7 +1695,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
/* vec: 4 items! */
- if( where_on_path(par, ctime, vec, dir) ) {
+ if( where_on_path(par, ctime, vec, dir, NULL, &radius) ) {
if(cu->flag & CU_FOLLOW) {
vectoquat(dir, ob->trackflag, ob->upflag, quat);
@@ -1701,6 +1712,13 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
QuatToMat4(quat, mat);
}
+ if(cu->flag & CU_PATH_RADIUS) {
+ float tmat[4][4], rmat[4][4];
+ Mat4Scale(tmat, radius);
+ Mat4MulMat4(rmat, mat, tmat);
+ Mat4CpyMat4(mat, rmat);
+ }
+
VECCOPY(mat[3], vec);
}
@@ -1798,7 +1816,7 @@ static void give_parvert(Object *par, int nr, float *vec)
count= 0;
while(nu && !found) {
- if((nu->type & 7)==CU_BEZIER) {
+ if(nu->type == CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 3e47c1006e5..0de97b9c703 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -63,6 +63,14 @@
#include "BKE_packedFile.h"
#include "BKE_report.h"
+#ifdef _WIN32
+#define open _open
+#define close _close
+#define read _read
+#define write _write
+#endif
+
+
int seekPackedFile(PackedFile *pf, int offset, int whence)
{
int oldseek = -1, seek = 0;
@@ -228,7 +236,7 @@ void packAll(Main *bmain, ReportList *reports)
// attempt to create a function that generates an unique filename
// this will work when all funtions in fileops.c understand relative filenames...
-char *find_new_name(char *name)
+static char *find_new_name(char *name)
{
char tempname[FILE_MAXDIR + FILE_MAXFILE];
char *newname;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 47b37c10689..954097d3a25 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -61,6 +61,7 @@
#include "BKE_anim.h"
#include "BKE_boids.h"
+#include "BKE_cloth.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_lattice.h"
@@ -93,10 +94,10 @@ static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, P
/* few helpers for countall etc. */
int count_particles(ParticleSystem *psys){
ParticleSettings *part=psys->part;
- ParticleData *pa;
- int tot=0,p;
+ PARTICLE_P;
+ int tot=0;
- for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++){
+ LOOP_PARTICLES {
if(pa->alive == PARS_KILLED);
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
@@ -107,10 +108,10 @@ int count_particles(ParticleSystem *psys){
}
int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
ParticleSettings *part=psys->part;
- ParticleData *pa;
- int tot=0,p;
+ PARTICLE_P;
+ int tot=0;
- for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++){
+ LOOP_PARTICLES {
if(pa->alive == PARS_KILLED);
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
@@ -121,10 +122,10 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
}
int psys_count_keys(ParticleSystem *psys)
{
- ParticleData *pa;
- int i, totpart=psys->totpart, totkey=0;
+ PARTICLE_P;
+ int totkey=0;
- for(i=0, pa=psys->particles; i<totpart; i++, pa++)
+ LOOP_PARTICLES
totkey += pa->totkey;
return totkey;
@@ -322,7 +323,7 @@ int psys_ob_has_hair(Object *ob)
}
int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
{
- return ((scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys==psys_get_current((scene->basact)->object) && psys->edit);
+ return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys==psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit));
}
int psys_check_enabled(Object *ob, ParticleSystem *psys)
{
@@ -367,33 +368,56 @@ void psys_free_settings(ParticleSettings *part)
boid_free_settings(part->boids);
}
-void free_hair(ParticleSystem *psys, int softbody)
+void free_hair(Object *ob, ParticleSystem *psys, int dynamics)
{
- ParticleData *pa;
- int i, totpart=psys->totpart;
+ PARTICLE_P;
- for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ if(psys->part->type != PART_HAIR)
+ return;
+
+ LOOP_PARTICLES {
if(pa->hair)
MEM_freeN(pa->hair);
pa->hair = NULL;
+ pa->totkey = 0;
}
psys->flag &= ~PSYS_HAIR_DONE;
- if(softbody && psys->soft) {
- sbFree(psys->soft);
- psys->soft = NULL;
+ if(psys->clmd) {
+ if(dynamics) {
+ BKE_ptcache_free_list(&psys->ptcaches);
+ psys->clmd->point_cache = psys->pointcache = NULL;
+ psys->clmd->ptcaches.first = psys->clmd->ptcaches.first = NULL;
+
+ modifier_free((ModifierData*)psys->clmd);
+
+ psys->clmd = NULL;
+ }
+ else {
+ cloth_free_modifier(ob, psys->clmd);
+ }
}
+
+ if(psys->hair_in_dm)
+ psys->hair_in_dm->release(psys->hair_in_dm);
+ psys->hair_in_dm = NULL;
+
+ if(psys->hair_out_dm)
+ psys->hair_out_dm->release(psys->hair_out_dm);
+ psys->hair_out_dm = NULL;
}
void free_keyed_keys(ParticleSystem *psys)
{
- ParticleData *pa;
- int i;
+ PARTICLE_P;
+
+ if(psys->part->type == PART_HAIR)
+ return;
if(psys->particles && psys->particles->keys) {
MEM_freeN(psys->particles->keys);
- for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++) {
+ LOOP_PARTICLES {
if(pa->keys) {
pa->keys= NULL;
pa->totkey= 0;
@@ -407,13 +431,20 @@ void free_child_path_cache(ParticleSystem *psys)
psys->childcache = NULL;
psys->totchildcache = 0;
}
-void psys_free_path_cache(ParticleSystem *psys)
+void psys_free_path_cache(ParticleSystem *psys, PTCacheEdit *edit)
{
- psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs);
- psys->pathcache= NULL;
- psys->totcached= 0;
+ if(edit) {
+ psys_free_path_cache_buffers(edit->pathcache, &edit->pathcachebufs);
+ edit->pathcache= NULL;
+ edit->totcached= 0;
+ }
+ if(psys) {
+ psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs);
+ psys->pathcache= NULL;
+ psys->totcached= 0;
- free_child_path_cache(psys);
+ free_child_path_cache(psys);
+ }
}
void psys_free_children(ParticleSystem *psys)
{
@@ -425,6 +456,29 @@ void psys_free_children(ParticleSystem *psys)
free_child_path_cache(psys);
}
+void psys_free_particles(ParticleSystem *psys)
+{
+ PARTICLE_P;
+
+ if(psys->particles) {
+ if(psys->part->type==PART_HAIR) {
+ LOOP_PARTICLES {
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+ }
+ }
+
+ if(psys->particles->keys)
+ MEM_freeN(psys->particles->keys);
+
+ if(psys->particles->boid)
+ MEM_freeN(psys->particles->boid);
+
+ MEM_freeN(psys->particles);
+ psys->particles= NULL;
+ psys->totpart= 0;
+ }
+}
/* free everything */
void psys_free(Object *ob, ParticleSystem * psys)
{
@@ -432,23 +486,14 @@ void psys_free(Object *ob, ParticleSystem * psys)
int nr = 0;
ParticleSystem * tpsys;
- psys_free_path_cache(psys);
+ psys_free_path_cache(psys, NULL);
- free_hair(psys, 1);
+ free_hair(ob, psys, 1);
- free_keyed_keys(psys);
+ psys_free_particles(psys);
if(psys->edit && psys->free_edit)
- psys->free_edit(psys);
-
- if(psys->particles){
- if(psys->particles->boid)
- MEM_freeN(psys->particles->boid);
-
- MEM_freeN(psys->particles);
- psys->particles = 0;
- psys->totpart = 0;
- }
+ psys->free_edit(psys->edit);
if(psys->child){
MEM_freeN(psys->child);
@@ -479,14 +524,11 @@ void psys_free(Object *ob, ParticleSystem * psys)
psys->part=0;
}
- if(psys->reactevents.first)
- BLI_freelistN(&psys->reactevents);
-
BKE_ptcache_free_list(&psys->ptcaches);
psys->pointcache = NULL;
- if(psys->targets.first)
- BLI_freelistN(&psys->targets);
+ BLI_freelistN(&psys->targets);
+ BLI_freelistN(&psys->reactevents);
BLI_kdtree_free(psys->tree);
@@ -646,7 +688,7 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
psmd->dm->release(psmd->dm);
}
- psys_free_path_cache(psys);
+ psys_free_path_cache(psys, NULL);
if(psys->child){
MEM_freeN(psys->child);
@@ -930,7 +972,7 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic
VecfCubicInterpol(keys[1].co, keys[1].vel, keys[2].co, keys[2].vel, dt, result->co, result->vel);
}
else {
- set_four_ipo(dt, t, type);
+ key_curve_position_weights(dt, t, type);
weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, result->co);
@@ -938,12 +980,12 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic
float temp[3];
if(dt>0.999f){
- set_four_ipo(dt-0.001f, t, type);
+ key_curve_position_weights(dt-0.001f, t, type);
weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp);
VECSUB(result->vel, result->co, temp);
}
else{
- set_four_ipo(dt+0.001f, t, type);
+ key_curve_position_weights(dt+0.001f, t, type);
weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp);
VECSUB(result->vel, temp, result->co);
}
@@ -954,17 +996,25 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic
typedef struct ParticleInterpolationData {
- ParticleKey *kkey[2];
HairKey *hkey[2];
- BodyPoint *bp[2];
- SoftBody *soft;
- int keyed, cached;
+
+ DerivedMesh *dm;
+ MVert *mvert[2];
+
+ int keyed;
+ ParticleKey *kkey[2];
+
+ PointCache *cache;
+
+ PTCacheEditPoint *epoint;
+ PTCacheEditKey *ekey[2];
+
float birthtime, dietime;
+ int bspline;
} ParticleInterpolationData;
/* Assumes pointcache->mem_cache exists, so for disk cached particles call psys_make_temp_pointcache() before use */
-static void get_pointcache_keys_for_time(Object *ob, ParticleSystem *psys, int index, float t, ParticleKey *key1, ParticleKey *key2)
+static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, int index, float t, ParticleKey *key1, ParticleKey *key2)
{
- PointCache *cache = psys->pointcache;
static PTCacheMem *pm = NULL; /* not thread safe */
if(index < 0) { /* initialize */
@@ -991,54 +1041,83 @@ static void get_pointcache_keys_for_time(Object *ob, ParticleSystem *psys, int i
static void init_particle_interpolation(Object *ob, ParticleSystem *psys, ParticleData *pa, ParticleInterpolationData *pind)
{
- if(pind->keyed) {
- pind->kkey[0] = pa->keys;
+ if(pind->epoint) {
+ PTCacheEditPoint *point = pind->epoint;
- if(pa->totkey > 1)
- pind->kkey[1] = pa->keys + 1;
- else
- pind->kkey[1] = NULL;
+ pind->ekey[0] = point->keys;
+ pind->ekey[1] = point->totkey > 1 ? point->keys + 1 : NULL;
- pind->birthtime = pa->keys->time;
- pind->dietime = (pa->keys + pa->totkey - 1)->time;
+ pind->birthtime = *(point->keys->time);
+ pind->dietime = *((point->keys + point->totkey - 1)->time);
}
- else if(pind->cached) {
- get_pointcache_keys_for_time(ob, psys, -1, 0.0f, NULL, NULL);
+ else if(pind->keyed) {
+ ParticleKey *key = pa->keys;
+ pind->kkey[0] = key;
+ pind->kkey[1] = pa->totkey > 1 ? key + 1 : NULL;
- pind->birthtime = pa->time;
- pind->dietime = pa->dietime;
+ pind->birthtime = key->time;
+ pind->dietime = (key + pa->totkey - 1)->time;
}
- else {
- pind->hkey[0] = pa->hair;
- pind->hkey[1] = pa->hair + 1;
+ else if(pind->cache) {
+ get_pointcache_keys_for_time(ob, pind->cache, -1, 0.0f, NULL, NULL);
- pind->birthtime = pa->hair->time;
- pind->dietime = (pa->hair + pa->totkey - 1)->time;
+ pind->birthtime = pa ? pa->time : pind->cache->startframe;
+ pind->dietime = pa ? pa->dietime : pind->cache->endframe;
}
+ else {
+ HairKey *key = pa->hair;
+ pind->hkey[0] = key;
+ pind->hkey[1] = key + 1;
- if(pind->soft) {
- pind->bp[0] = pind->soft->bpoint + pa->bpi;
- pind->bp[1] = pind->soft->bpoint + pa->bpi + 1;
+ pind->birthtime = key->time;
+ pind->dietime = (key + pa->totkey - 1)->time;
+
+ if(pind->dm) {
+ pind->mvert[0] = CDDM_get_vert(pind->dm, pa->hair_index);
+ pind->mvert[1] = pind->mvert[0] + 1;
+ }
+ }
+}
+static void edit_to_particle(ParticleKey *key, PTCacheEditKey *ekey)
+{
+ VECCOPY(key->co, ekey->co);
+ if(ekey->vel) {
+ VECCOPY(key->vel, ekey->vel);
}
+ key->time = *(ekey->time);
}
static void hair_to_particle(ParticleKey *key, HairKey *hkey)
{
VECCOPY(key->co, hkey->co);
key->time = hkey->time;
}
-static void bp_to_particle(ParticleKey *key, BodyPoint *bp, HairKey *hkey)
+
+static void mvert_to_particle(ParticleKey *key, MVert *mvert, HairKey *hkey)
{
- VECCOPY(key->co, bp->pos);
+ VECCOPY(key->co, mvert->co);
key->time = hkey->time;
}
static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData *pa, float t, float frs_sec, ParticleInterpolationData *pind, ParticleKey *result)
{
+ PTCacheEditPoint *point = pind->epoint;
ParticleKey keys[4];
+ int point_vel = (point && point->keys->vel);
float real_t, dfra, keytime;
/* interpret timing and find keys */
- if(pind->keyed) {
+ if(point) {
+ if(result->time < 0.0f)
+ real_t = -result->time;
+ else
+ real_t = *(pind->ekey[0]->time) + t * (*(pind->ekey[0][point->totkey-1].time) - *(pind->ekey[0]->time));
+
+ while(*(pind->ekey[1]->time) < real_t)
+ pind->ekey[1]++;
+
+ pind->ekey[0] = pind->ekey[1] - 1;
+ }
+ else if(pind->keyed) {
/* we have only one key, so let's use that */
if(pind->kkey[1]==NULL) {
copy_particle_key(result, pind->kkey[0], 1);
@@ -1075,7 +1154,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
pind->kkey[0] = pind->kkey[1] - 1;
}
- else if(pind->cached) {
+ else if(pind->cache) {
if(result->time < 0.0f) /* flag for time in frames */
real_t = -result->time;
else
@@ -1089,24 +1168,28 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
while(pind->hkey[1]->time < real_t) {
pind->hkey[1]++;
- pind->bp[1]++;
+ pind->mvert[1]++;
}
pind->hkey[0] = pind->hkey[1] - 1;
}
/* set actual interpolation keys */
- if(pind->soft) {
- pind->bp[0] = pind->bp[1] - 1;
- bp_to_particle(keys + 1, pind->bp[0], pind->hkey[0]);
- bp_to_particle(keys + 2, pind->bp[1], pind->hkey[1]);
+ if(point) {
+ edit_to_particle(keys + 1, pind->ekey[0]);
+ edit_to_particle(keys + 2, pind->ekey[1]);
+ }
+ else if(pind->dm) {
+ pind->mvert[0] = pind->mvert[1] - 1;
+ mvert_to_particle(keys + 1, pind->mvert[0], pind->hkey[0]);
+ mvert_to_particle(keys + 2, pind->mvert[1], pind->hkey[1]);
}
else if(pind->keyed) {
memcpy(keys + 1, pind->kkey[0], sizeof(ParticleKey));
memcpy(keys + 2, pind->kkey[1], sizeof(ParticleKey));
}
- else if(pind->cached) {
- get_pointcache_keys_for_time(NULL, psys, p, real_t, keys+1, keys+2);
+ else if(pind->cache) {
+ get_pointcache_keys_for_time(NULL, pind->cache, p, real_t, keys+1, keys+2);
}
else {
hair_to_particle(keys + 1, pind->hkey[0]);
@@ -1114,12 +1197,18 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
}
/* set secondary interpolation keys for hair */
- if(!pind->keyed && !pind->cached) {
- if(pind->soft) {
+ if(!pind->keyed && !pind->cache && !point_vel) {
+ if(point) {
+ if(pind->ekey[0] != point->keys)
+ edit_to_particle(keys, pind->ekey[0] - 1);
+ else
+ edit_to_particle(keys, pind->ekey[0]);
+ }
+ else if(pind->dm) {
if(pind->hkey[0] != pa->hair)
- bp_to_particle(keys, pind->bp[0] - 1, pind->hkey[0] - 1);
+ mvert_to_particle(keys, pind->mvert[0] - 1, pind->hkey[0] - 1);
else
- bp_to_particle(keys, pind->bp[0], pind->hkey[0]);
+ mvert_to_particle(keys, pind->mvert[0], pind->hkey[0]);
}
else {
if(pind->hkey[0] != pa->hair)
@@ -1128,11 +1217,17 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
hair_to_particle(keys, pind->hkey[0]);
}
- if(pind->soft) {
+ if(point) {
+ if(pind->ekey[1] != point->keys + point->totkey - 1)
+ edit_to_particle(keys + 3, pind->ekey[1] + 1);
+ else
+ edit_to_particle(keys + 3, pind->ekey[1]);
+ }
+ else if(pind->dm) {
if(pind->hkey[1] != pa->hair + pa->totkey - 1)
- bp_to_particle(keys + 3, pind->bp[1] + 1, pind->hkey[1] + 1);
+ mvert_to_particle(keys + 3, pind->mvert[1] + 1, pind->hkey[1] + 1);
else
- bp_to_particle(keys + 3, pind->bp[1], pind->hkey[1]);
+ mvert_to_particle(keys + 3, pind->mvert[1], pind->hkey[1]);
}
else {
if(pind->hkey[1] != pa->hair + pa->totkey - 1)
@@ -1146,19 +1241,19 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
keytime = (real_t - keys[1].time) / dfra;
/* convert velocity to timestep size */
- if(pind->keyed || pind->cached){
+ if(pind->keyed || pind->cache || point_vel){
VecMulf(keys[1].vel, dfra / frs_sec);
VecMulf(keys[2].vel, dfra / frs_sec);
QuatInterpol(result->rot,keys[1].rot,keys[2].rot,keytime);
}
/* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/
- psys_interpolate_particle((pind->keyed || pind->cached) ? -1 /* signal for cubic interpolation */
- : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
+ psys_interpolate_particle((pind->keyed || pind->cache || point_vel) ? -1 /* signal for cubic interpolation */
+ : (pind->bspline ? KEY_BSPLINE : KEY_CARDINAL)
,keys, keytime, result, 1);
/* the velocity needs to be converted back from cubic interpolation */
- if(pind->keyed || pind->cached)
+ if(pind->keyed || pind->cache || point_vel)
VecMulf(result->vel, frs_sec / dfra);
}
/************************************************/
@@ -1611,7 +1706,7 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys)
}
}
}
- return 0;
+ return NULL;
}
/************************************************/
/* Particles on a shape */
@@ -1838,7 +1933,7 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase
ParticleKey key, par;
float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0;
- float guidevec[4], guidedir[3], rot2[4], temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f};
+ float guidevec[4], guidedir[3], rot2[4], radius, temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f};
float veffect[3]={0.0,0.0,0.0}, guidetime;
effect[0]=effect[1]=effect[2]=0.0;
@@ -1881,9 +1976,9 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase
}
if(pd->flag & PFIELD_GUIDE_PATH_ADD)
- where_on_path(eob, f_force*guidetime, guidevec, guidedir);
+ where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, &radius);
else
- where_on_path(eob, guidetime, guidevec, guidedir);
+ where_on_path(eob, guidetime, guidevec, guidedir, NULL, &radius);
Mat4MulVecfl(ec->ob->obmat,guidevec);
Mat4Mul3Vecfl(ec->ob->obmat,guidedir);
@@ -1913,10 +2008,12 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase
/* curve taper */
if(cu->taperobj)
VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100));
- /* TODO */
- //else{
- ///* curve size*/
- //}
+
+ else{ /* curve size*/
+ if(cu->flag & CU_PATH_RADIUS) {
+ VecMulf(pa_loc, radius);
+ }
+ }
par.co[0]=par.co[1]=par.co[2]=0.0f;
VECCOPY(key.co,pa_loc);
do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0);
@@ -2038,7 +2135,11 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup)
{
float *vg=0;
- if(psys->vgroup[vgroup]){
+ if(vgroup < 0) {
+ /* hair dynamics pinning vgroup */
+
+ }
+ else if(psys->vgroup[vgroup]){
MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
if(dvert){
int totvert=dm->getNumVerts(dm), i;
@@ -2130,7 +2231,7 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
/*---start figuring out what is actually wanted---*/
if(psys_in_edit_mode(scene, psys))
- if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_SHOW_CHILD)==0)
+ if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0)
totchild=0;
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
@@ -2246,7 +2347,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
needupdate= 0;
w= 0;
while(w<4 && cpa->pa[w]>=0) {
- if(psys->particles[cpa->pa[w]].flag & PARS_EDIT_RECALC) {
+ if(psys->edit->points[cpa->pa[w]].flag & PEP_EDIT_RECALC) {
needupdate= 1;
break;
}
@@ -2289,7 +2390,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
}
else{
if(ctx->editupdate && !(part->flag & PART_BRANCHING)) {
- if(!(psys->particles[cpa->parent].flag & PARS_EDIT_RECALC))
+ if(!(psys->edit->points[cpa->parent].flag & PEP_EDIT_RECALC))
return;
memset(keys, 0, sizeof(*keys)*(ctx->steps+1));
@@ -2502,6 +2603,9 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
ListBase threads;
int i, totchild, totparent, totthread;
+ if(psys->flag & PSYS_GLOBAL_HAIR)
+ return;
+
pthreads= psys_threads_create(scene, ob, psys);
if(!psys_threads_init_path(pthreads, scene, cfra, editupdate)) {
@@ -2558,158 +2662,111 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
/* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */
/* -Makes child strands possible and creates them too into the cache. */
/* -Cached path data is also used to determine cut position for the editmode tool. */
-void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int editupdate)
+void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra)
{
- ParticleCacheKey *ca, **cache=psys->pathcache;
+ ParticleCacheKey *ca, **cache= psys->pathcache;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- ParticleEditSettings *pset = &scene->toolsettings->particle;
ParticleSettings *part = psys->part;
+ ParticleEditSettings *pset = &scene->toolsettings->particle;
+
+ DerivedMesh *hair_dm = psys->hair_out_dm;
- ParticleData *pa;
+ ParticleData *pa = psys->particles;
ParticleKey result;
-
- ParticleEdit *edit = 0;
- ParticleEditKey *ekey = 0;
-
- SoftBody *soft = 0;
- BodyPoint *bp[2] = {NULL, NULL};
Material *ma;
-
ParticleInterpolationData pind;
float birthtime = 0.0, dietime = 0.0;
- float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec;
+ float t, time = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec;
float col[4] = {0.5f, 0.5f, 0.5f, 1.0f};
float prev_tangent[3], hairmat[4][4];
float rotmat[3][3];
int k,i;
- int steps = (int)pow(2.0, (double)psys->part->draw_step);
+ int steps = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step));
int totpart = psys->totpart;
- float sel_col[3];
- float nosel_col[3];
float length, vec[3];
float *vg_effector= NULL, effector=0.0f;
float *vg_length= NULL, pa_length=1.0f;
int keyed, baked;
/* we don't have anything valid to create paths from so let's quit here */
- if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0 && (psys->pointcache->flag & PTCACHE_BAKED)==0)
+ if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
return;
+ if(psys_in_edit_mode(scene, psys))
+ if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0)
+ return;
+
BLI_srandom(psys->seed);
keyed = psys->flag & PSYS_KEYED;
- baked = psys->pointcache->flag & PTCACHE_BAKED;
+ baked = !hair_dm && psys->pointcache->flag & PTCACHE_BAKED;
- if(psys->renderdata) {
- steps = (int)pow(2.0, (double)psys->part->ren_step);
- }
- else if(psys_in_edit_mode(scene, psys)) {
- edit=psys->edit;
-
- //timed = edit->draw_timed;
-
- if(pset->brushtype == PE_BRUSH_WEIGHT) {
- sel_col[0] = sel_col[1] = sel_col[2] = 1.0f;
- nosel_col[0] = nosel_col[1] = nosel_col[2] = 0.0f;
- }
- else{
- sel_col[0] = (float)edit->sel_col[0] / 255.0f;
- sel_col[1] = (float)edit->sel_col[1] / 255.0f;
- sel_col[2] = (float)edit->sel_col[2] / 255.0f;
- nosel_col[0] = (float)edit->nosel_col[0] / 255.0f;
- nosel_col[1] = (float)edit->nosel_col[1] / 255.0f;
- nosel_col[2] = (float)edit->nosel_col[2] / 255.0f;
- }
- }
+ /* clear out old and create new empty path cache */
+ psys_free_path_cache(psys, psys->edit);
+ cache= psys->pathcache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1);
- if(editupdate && psys->pathcache && totpart == psys->totcached) {
- cache = psys->pathcache;
- }
- else {
- /* clear out old and create new empty path cache */
- psys_free_path_cache(psys);
- cache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1);
- psys->pathcache= cache;
- }
-
- if(edit==NULL && psys->soft && psys->softflag & OB_SB_ENABLE) {
- soft = psys->soft;
- if(!soft->bpoint)
- soft= NULL;
- }
-
psys->lattice = psys_get_lattice(scene, ob, psys);
ma= give_current_material(ob, psys->part->omat);
if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
VECCOPY(col, &ma->r)
-
- if(psys->part->from!=PART_FROM_PARTICLE) {
+
+ if(psys->part->from!=PART_FROM_PARTICLE && !(psys->flag & PSYS_GLOBAL_HAIR)) {
if(!(psys->part->flag & PART_CHILD_EFFECT))
vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR);
- if(!edit && !psys->totchild)
+ if(!psys->totchild)
vg_length = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_LENGTH);
}
/*---first main loop: create all actual particles' paths---*/
- for(i=0,pa=psys->particles; i<totpart; i++, pa++){
- if(psys && edit==NULL && (pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST)) {
- if(soft)
- bp[0] += pa->totkey; /* TODO use of initialized value? */
+ for(i=0; i<totpart; i++, pa++){
+ if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST)
continue;
- }
- if(editupdate && !(pa->flag & PARS_EDIT_RECALC)) continue;
- else memset(cache[i], 0, sizeof(*cache[i])*(steps+1));
-
- if(!edit && !psys->totchild) {
- pa_length = 1.0f - part->randlength * 0.5 * (1.0f + pa->r_ave[0]);
+ if(!psys->totchild) {
+ BLI_srandom(psys->seed + i);
+ pa_length = 1.0f - part->randlength * BLI_frand();
if(vg_length)
pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length);
}
- cache[i]->steps = steps;
+ pind.keyed = keyed;
+ pind.cache = baked ? psys->pointcache : NULL;
+ pind.epoint = NULL;
+ pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
+ pind.dm = hair_dm;
+
+ memset(cache[i], 0, sizeof(*cache[i])*(steps+1));
- if(edit)
- ekey = edit->keys[i];
+ cache[i]->steps = steps;
/*--get the first data points--*/
- pind.keyed = keyed;
- pind.cached = baked;
- pind.soft = soft;
init_particle_interpolation(ob, psys, pa, &pind);
-
/* hairmat is needed for for non-hair particle too so we get proper rotations */
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
VECCOPY(rotmat[0], hairmat[2]);
VECCOPY(rotmat[1], hairmat[1]);
VECCOPY(rotmat[2], hairmat[0]);
- if(!edit) {
- if(part->draw & PART_ABS_PATH_TIME) {
- birthtime = MAX2(pind.birthtime, part->path_start);
- dietime = MIN2(pind.dietime, part->path_end);
- }
- else {
- float tb = pind.birthtime;
- birthtime = tb + part->path_start * (pind.dietime - tb);
- dietime = tb + part->path_end * (pind.dietime - tb);
- }
-
- if(birthtime >= dietime) {
- cache[i]->steps = -1;
- continue;
- }
+ if(part->draw & PART_ABS_PATH_TIME) {
+ birthtime = MAX2(pind.birthtime, part->path_start);
+ dietime = MIN2(pind.dietime, part->path_end);
+ }
+ else {
+ float tb = pind.birthtime;
+ birthtime = tb + part->path_start * (pind.dietime - tb);
+ dietime = tb + part->path_end * (pind.dietime - tb);
+ }
- dietime = birthtime + pa_length * (dietime - birthtime);
+ if(birthtime >= dietime) {
+ cache[i]->steps = -1;
+ continue;
}
- else
- /* XXX brecht: don't know if this code from 2.4 is correct
- * still, but makes hair appear again in particle mode */
- dietime= pind.hkey[0][pa->totkey-1].time;
+
+ dietime = birthtime + pa_length * (dietime - birthtime);
/*--interpolate actual path from data points--*/
for(k=0, ca=cache[i]; k<=steps; k++, ca++){
@@ -2721,46 +2778,16 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result);
- /* keyed, baked and softbody are allready in global space */
- if(!keyed && !baked && !soft) {
+ /* dynamic hair is in object space */
+ /* keyed and baked are allready in global space */
+ if(hair_dm)
+ Mat4MulVecfl(ob->obmat, result.co);
+ else if(!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR))
Mat4MulVecfl(hairmat, result.co);
- }
VECCOPY(ca->co, result.co);
-
- /* selection coloring in edit mode */
- if(edit){
- if(pset->brushtype==PE_BRUSH_WEIGHT){
- if(k==steps)
- VecLerpf(ca->col, nosel_col, sel_col, pind.hkey[0]->weight);
- else
- VecLerpf(ca->col, nosel_col, sel_col,
- (1.0f - keytime) * pind.hkey[0]->weight + keytime * pind.hkey[1]->weight);
- }
- else{
- if((ekey + (pind.hkey[0] - pa->hair))->flag & PEK_SELECT){
- if((ekey + (pind.hkey[1] - pa->hair))->flag & PEK_SELECT){
- VECCOPY(ca->col, sel_col);
- }
- else{
- VecLerpf(ca->col, sel_col, nosel_col, keytime);
- }
- }
- else{
- if((ekey + (pind.hkey[1] - pa->hair))->flag & PEK_SELECT){
- VecLerpf(ca->col, nosel_col, sel_col, keytime);
- }
- else{
- VECCOPY(ca->col, nosel_col);
- }
- }
- }
- }
- else{
- VECCOPY(ca->col, col);
- }
+ VECCOPY(ca->col, col);
}
-
/*--modify paths and calculate rotation & velocity--*/
@@ -2772,64 +2799,66 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
effector*= psys_particle_value_from_verts(psmd->dm,psys->part->from,pa,vg_effector);
for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
+ if(!(psys->flag & PSYS_GLOBAL_HAIR)) {
/* apply effectors */
- if(!(psys->part->flag & PART_CHILD_EFFECT) && edit==0 && k)
- do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
+ if(!(psys->part->flag & PART_CHILD_EFFECT) && k)
+ do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
- /* apply guide curves to path data */
- if(edit==0 && psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
- /* ca is safe to cast, since only co and vel are used */
- do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
+ /* apply guide curves to path data */
+ if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
+ /* ca is safe to cast, since only co and vel are used */
+ do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
- /* apply lattice */
- if(psys->lattice && edit==0)
- calc_latt_deform(psys->lattice, ca->co, 1.0f);
+ /* apply lattice */
+ if(psys->lattice)
+ calc_latt_deform(psys->lattice, ca->co, 1.0f);
- /* figure out rotation */
-
- if(k) {
- float cosangle, angle, tangent[3], normal[3], q[4];
-
- if(k == 1) {
- /* calculate initial tangent for incremental rotations */
- VECSUB(tangent, ca->co, (ca - 1)->co);
- VECCOPY(prev_tangent, tangent);
- Normalize(prev_tangent);
-
- /* First rotation is based on emitting face orientation. */
- /* This is way better than having flipping rotations resulting */
- /* from using a global axis as a rotation pole (vec_to_quat()). */
- /* It's not an ideal solution though since it disregards the */
- /* initial tangent, but taking that in to account will allow */
- /* the possibility of flipping again. -jahka */
- Mat3ToQuat_is_ok(rotmat, (ca-1)->rot);
- }
- else {
- VECSUB(tangent, ca->co, (ca - 1)->co);
- Normalize(tangent);
-
- cosangle= Inpf(tangent, prev_tangent);
-
- /* note we do the comparison on cosangle instead of
- * angle, since floating point accuracy makes it give
- * different results across platforms */
- if(cosangle > 0.999999f) {
- QUATCOPY((ca - 1)->rot, (ca - 2)->rot);
+ /* figure out rotation */
+
+ if(k) {
+ float cosangle, angle, tangent[3], normal[3], q[4];
+
+ if(k == 1) {
+ /* calculate initial tangent for incremental rotations */
+ VECSUB(tangent, ca->co, (ca - 1)->co);
+ VECCOPY(prev_tangent, tangent);
+ Normalize(prev_tangent);
+
+ /* First rotation is based on emitting face orientation. */
+ /* This is way better than having flipping rotations resulting */
+ /* from using a global axis as a rotation pole (vec_to_quat()). */
+ /* It's not an ideal solution though since it disregards the */
+ /* initial tangent, but taking that in to account will allow */
+ /* the possibility of flipping again. -jahka */
+ Mat3ToQuat_is_ok(rotmat, (ca-1)->rot);
}
else {
- angle= saacos(cosangle);
- Crossf(normal, prev_tangent, tangent);
- VecRotToQuat(normal, angle, q);
- QuatMul((ca - 1)->rot, q, (ca - 2)->rot);
+ VECSUB(tangent, ca->co, (ca - 1)->co);
+ Normalize(tangent);
+
+ cosangle= Inpf(tangent, prev_tangent);
+
+ /* note we do the comparison on cosangle instead of
+ * angle, since floating point accuracy makes it give
+ * different results across platforms */
+ if(cosangle > 0.999999f) {
+ QUATCOPY((ca - 1)->rot, (ca - 2)->rot);
+ }
+ else {
+ angle= saacos(cosangle);
+ Crossf(normal, prev_tangent, tangent);
+ VecRotToQuat(normal, angle, q);
+ QuatMul((ca - 1)->rot, q, (ca - 2)->rot);
+ }
+
+ VECCOPY(prev_tangent, tangent);
}
- VECCOPY(prev_tangent, tangent);
+ if(k == steps)
+ QUATCOPY(ca->rot, (ca - 1)->rot);
}
- if(k == steps)
- QUATCOPY(ca->rot, (ca - 1)->rot);
}
-
/* set velocity */
@@ -2857,6 +2886,123 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
if(vg_length)
MEM_freeN(vg_length);
}
+void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cfra)
+{
+ ParticleCacheKey *ca, **cache= edit->pathcache;
+ ParticleEditSettings *pset = &scene->toolsettings->particle;
+
+ PTCacheEditPoint *point = edit->points;
+ PTCacheEditKey *ekey = NULL;
+
+ ParticleSystem *psys = edit->psys;
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
+ ParticleData *pa = psys ? psys->particles : NULL;
+
+ ParticleInterpolationData pind;
+ ParticleKey result;
+
+ float birthtime = 0.0, dietime = 0.0;
+ float t, time = 0.0, keytime = 0.0, frs_sec;
+ float hairmat[4][4];
+ int k,i;
+ int steps = (int)pow(2.0, (double)pset->draw_step);
+ int totpart = edit->totpoint;
+ float sel_col[3];
+ float nosel_col[3];
+
+ steps = MAX2(steps, 4);
+
+ if(!cache || edit->totpoint != edit->totcached) {
+ /* clear out old and create new empty path cache */
+ psys_free_path_cache(edit->psys, edit);
+ cache= edit->pathcache= psys_alloc_path_cache_buffers(&edit->pathcachebufs, totpart, steps+1);
+ }
+
+ frs_sec = (psys || edit->pid.flag & PTCACHE_VEL_PER_SEC) ? 25.0f : 1.0f;
+
+ sel_col[0] = (float)edit->sel_col[0] / 255.0f;
+ sel_col[1] = (float)edit->sel_col[1] / 255.0f;
+ sel_col[2] = (float)edit->sel_col[2] / 255.0f;
+ nosel_col[0] = (float)edit->nosel_col[0] / 255.0f;
+ nosel_col[1] = (float)edit->nosel_col[1] / 255.0f;
+ nosel_col[2] = (float)edit->nosel_col[2] / 255.0f;
+
+ /*---first main loop: create all actual particles' paths---*/
+ for(i=0; i<totpart; i++, pa+=pa?1:0, point++){
+ if(edit->totcached && !(point->flag & PEP_EDIT_RECALC))
+ continue;
+
+ ekey = point->keys;
+
+ pind.keyed = 0;
+ pind.cache = NULL;
+ pind.epoint = point;
+ pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0;
+ pind.dm = NULL;
+
+ memset(cache[i], 0, sizeof(*cache[i])*(steps+1));
+
+ cache[i]->steps = steps;
+
+ /*--get the first data points--*/
+ init_particle_interpolation(ob, psys, pa, &pind);
+
+ if(psys)
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+
+ birthtime = pind.birthtime;
+ dietime = pind.dietime;
+
+ if(birthtime >= dietime) {
+ cache[i]->steps = -1;
+ continue;
+ }
+
+ /*--interpolate actual path from data points--*/
+ for(k=0, ca=cache[i]; k<=steps; k++, ca++){
+ time = (float)k / (float)steps;
+
+ t = birthtime + time * (dietime - birthtime);
+
+ result.time = -t;
+
+ do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result);
+
+ /* non-hair points are allready in global space */
+ if(psys && !(psys->flag & PSYS_GLOBAL_HAIR))
+ Mat4MulVecfl(hairmat, result.co);
+
+ VECCOPY(ca->co, result.co);
+
+ ca->vel[0] = ca->vel[1] = 0.0f;
+ ca->vel[1] = 1.0f;
+
+ /* selection coloring in edit mode */
+ if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){
+ if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){
+ VECCOPY(ca->col, sel_col);
+ }
+ else{
+ keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
+ VecLerpf(ca->col, sel_col, nosel_col, keytime);
+ }
+ }
+ else{
+ if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){
+ keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
+ VecLerpf(ca->col, nosel_col, sel_col, keytime);
+ }
+ else{
+ VECCOPY(ca->col, nosel_col);
+ }
+ }
+
+ ca->time = t;
+ }
+ }
+
+ edit->totcached = totpart;
+}
/************************************************/
/* Particle Key handling */
/************************************************/
@@ -3057,7 +3203,7 @@ void object_add_particle_system(Scene *scene, Object *ob)
psys->cfra=bsystem_time(scene,ob,scene->r.cfra+1,0.0);
DAG_scene_sort(scene);
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
}
void object_remove_particle_system(Scene *scene, Object *ob)
{
@@ -3080,7 +3226,7 @@ void object_remove_particle_system(Scene *scene, Object *ob)
((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT;
DAG_scene_sort(scene);
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
}
static void default_particle_settings(ParticleSettings *part)
{
@@ -3260,7 +3406,7 @@ void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int reca
}
}
if(flush)
- DAG_object_flush_update(scene, base->object, OB_RECALC_DATA);
+ DAG_id_flush_update(&base->object->id, OB_RECALC_DATA);
}
}
@@ -3292,7 +3438,7 @@ LinkNode *psys_using_settings(struct Scene *scene, ParticleSettings *part, int f
}
if(flush_update && found)
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
}
return node;
@@ -3471,6 +3617,8 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd,
{
ParticleTexture ptex;
float size=1.0f;
+
+ BLI_srandom(psys->seed + (pa - psys->particles) + 100);
if(ma && part->from!=PART_FROM_PARTICLE){
ptex.size=size;
@@ -3489,7 +3637,7 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd,
size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size);
if(part->randsize!=0.0)
- size*= 1.0f - part->randsize*pa->sizemul;
+ size*= 1.0f - part->randsize * BLI_frand();
return size*part->size;
}
@@ -3656,16 +3804,10 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
if(p<totpart){
pa = psys->particles + p;
-
- if(pa->alive==PARS_DEAD && part->flag & PART_STICKY && pa->flag & PARS_STICKY && pa->stick_ob){
- copy_particle_key(state,&pa->state,0);
- key_from_object(pa->stick_ob,state);
- return;
- }
-
pind.keyed = keyed;
- pind.cached = cached;
- pind.soft = NULL;
+ pind.cache = cached ? psys->pointcache : NULL;
+ pind.epoint = NULL;
+ pind.dm = psys->hair_out_dm;
init_particle_interpolation(ob, psys, pa, &pind);
do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state);
@@ -3877,20 +4019,11 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
return 0; /* currently not supported */
else if(psys->totchild && p>=psys->totpart){
ChildParticle *cpa=psys->child+p-psys->totpart;
- ParticleKey *key1, skey;
+ ParticleKey *key1;
float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime;
pa = psys->particles + cpa->parent;
-
- if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob) {
- key1 = &skey;
- copy_particle_key(key1,&pa->state,0);
- key_from_object(pa->stick_ob,key1);
- }
- else {
- key1=&pa->state;
- }
-
+ key1=&pa->state;
offset_child(cpa, key1, state, part->childflat, part->childrad);
CLAMP(t,0.0,1.0);
@@ -3947,10 +4080,6 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
}
}
- if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob){
- key_from_object(pa->stick_ob,state);
- }
-
if(psys->lattice)
calc_latt_deform(psys->lattice, state->co,1.0f);
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 8db4656239b..663d5c6ee03 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -73,7 +73,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
#include "BKE_material.h"
-#include "BKE_softbody.h"
+#include "BKE_cloth.h"
#include "BKE_depsgraph.h"
#include "BKE_lattice.h"
#include "BKE_pointcache.h"
@@ -123,21 +123,11 @@ static int get_current_display_percentage(ParticleSystem *psys)
void psys_reset(ParticleSystem *psys, int mode)
{
ParticleSettings *part= psys->part;
- ParticleData *pa;
- int i;
+ PARTICLE_P;
if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) {
- if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->flag & PSYS_EDITED))) {
- if(psys->particles) {
- if(psys->particles->keys)
- MEM_freeN(psys->particles->keys);
-
- for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++)
- if(pa->hair) MEM_freeN(pa->hair);
-
- MEM_freeN(psys->particles);
- psys->particles= NULL;
- }
+ if(mode == PSYS_RESET_ALL || !(psys->flag & PSYS_EDITED)) {
+ psys_free_particles(psys);
psys->totpart= 0;
psys->totkeyed= 0;
@@ -145,14 +135,17 @@ void psys_reset(ParticleSystem *psys, int mode)
if(psys->reactevents.first)
BLI_freelistN(&psys->reactevents);
+
+ if(psys->edit && psys->free_edit) {
+ psys->free_edit(psys->edit);
+ psys->edit = NULL;
+ psys->free_edit = NULL;
+ }
}
}
else if(mode == PSYS_RESET_CACHE_MISS) {
/* set all particles to be skipped */
- ParticleData *pa = psys->particles;
- int p=0;
-
- for(; p<psys->totpart; p++, pa++)
+ LOOP_PARTICLES
pa->flag |= PARS_NO_DISP;
}
@@ -165,7 +158,7 @@ void psys_reset(ParticleSystem *psys, int mode)
psys->totchild= 0;
/* reset path cache */
- psys_free_path_cache(psys);
+ psys_free_path_cache(psys, psys->edit);
/* reset point cache */
psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID;
@@ -174,9 +167,10 @@ void psys_reset(ParticleSystem *psys, int mode)
static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
{
- ParticleData *newpars = 0, *pa;
- BoidData *newboids = 0;
- int i, totpart, totsaved = 0;
+ ParticleData *newpars = NULL;
+ BoidParticle *newboids = NULL;
+ PARTICLE_P;
+ int totpart, totsaved = 0;
if(new_totpart<0) {
if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
@@ -189,47 +183,46 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
else
totpart=new_totpart;
- if(totpart) {
+ if(totpart && totpart != psys->totpart) {
newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
+
+ if(psys->particles) {
+ totsaved=MIN2(psys->totpart,totpart);
+ /*save old pars*/
+ if(totsaved) {
+ memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
+
+ if(psys->particles->boid)
+ memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidParticle));
+ }
- if(psys->part->phystype == PART_PHYS_BOIDS)
- newboids = MEM_callocN(totpart*sizeof(BoidData), "Boid Data");
- }
- if(psys->particles) {
- totsaved=MIN2(psys->totpart,totpart);
- /*save old pars*/
- if(totsaved) {
- memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
-
- if(newboids)
- memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidData));
- }
-
- if(psys->particles->keys)
- MEM_freeN(psys->particles->keys);
+ if(psys->particles->keys)
+ MEM_freeN(psys->particles->keys);
- if(psys->particles->boid)
- MEM_freeN(psys->particles->boid);
+ if(psys->particles->boid)
+ MEM_freeN(psys->particles->boid);
- for(i=0, pa=newpars; i<totsaved; i++, pa++) {
- if(pa->keys) {
- pa->keys= NULL;
- pa->totkey= 0;
+ for(p=0, pa=newpars; p<totsaved; p++, pa++) {
+ if(pa->keys) {
+ pa->keys= NULL;
+ pa->totkey= 0;
+ }
}
- }
- for(i=totsaved, pa=psys->particles+totsaved; i<psys->totpart; i++, pa++)
- if(pa->hair) MEM_freeN(pa->hair);
+ for(p=totsaved, pa=psys->particles+totsaved; p<psys->totpart; p++, pa++)
+ if(pa->hair) MEM_freeN(pa->hair);
- MEM_freeN(psys->particles);
- }
- psys->particles=newpars;
+ MEM_freeN(psys->particles);
+ }
+
+ psys->particles=newpars;
- if(newboids) {
- pa = psys->particles;
- pa->boid = newboids;
- for(i=1, pa++; i<totpart; i++,pa++)
- pa->boid = (pa-1)->boid + 1;
+ if(newboids) {
+ LOOP_PARTICLES
+ pa->boid = newboids++;
+ }
+
+ psys->totpart=totpart;
}
if(psys->child) {
@@ -237,8 +230,6 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
psys->child=0;
psys->totchild=0;
}
-
- psys->totpart=totpart;
}
static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys)
@@ -285,8 +276,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
each original elements can reference its derived elements
*/
Mesh *me= (Mesh*)ob->data;
- ParticleData *pa= 0;
- int p;
+ PARTICLE_P;
/* CACHE LOCATIONS */
if(!dm->deformedOnly) {
@@ -323,7 +313,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
}
/* cache the verts/faces! */
- for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
+ LOOP_PARTICLES {
if(psys->part->from == PART_FROM_VERT) {
if(nodearray[pa->num])
pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
@@ -343,7 +333,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
* should know to use the num or num_dmcache, set the num_dmcache to
* an invalid value, just incase */
- for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++)
+ LOOP_PARTICLES
pa->num_dmcache = -1;
}
}
@@ -1443,12 +1433,11 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec
/* ready for future use, to emit particles without geometry */
static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from)
{
- ParticleData *pa;
- int totpart=psys->totpart, p;
+ PARTICLE_P;
fprintf(stderr,"Shape emission not yet possible!\n");
- for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ LOOP_PARTICLES {
pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
pa->foffset= 0.0f;
pa->num= -1;
@@ -1470,12 +1459,11 @@ static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys,
distribute_particles_on_shape(ob,psys,from);
if(distr_error){
- ParticleData *pa;
- int totpart=psys->totpart, p;
+ PARTICLE_P;
fprintf(stderr,"Particle distribution error!\n");
- for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ LOOP_PARTICLES {
pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
pa->foffset= 0.0f;
pa->num= -1;
@@ -1570,7 +1558,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
Material *ma=0;
//IpoCurve *icu=0; // XXX old animation system
int totpart;
- float rand,length;
+ float rand;
part=psys->part;
@@ -1625,40 +1613,8 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
pa->dietime= pa->time+pa->lifetime;
- pa->sizemul= BLI_frand();
-
- rand= BLI_frand();
-
- /* while loops are to have a spherical distribution (avoid cubic distribution) */
- if(part->phystype != PART_PHYS_BOIDS) {
- /* boids store gravity in r_ve, so skip here */
- length=2.0f;
- while(length>1.0){
- pa->r_ve[0]=2.0f*(BLI_frand()-0.5f);
- pa->r_ve[1]=2.0f*(BLI_frand()-0.5f);
- pa->r_ve[2]=2.0f*(BLI_frand()-0.5f);
- length=VecLength(pa->r_ve);
- }
- }
-
- length=2.0f;
- while(length>1.0){
- pa->r_ave[0]=2.0f*(BLI_frand()-0.5f);
- pa->r_ave[1]=2.0f*(BLI_frand()-0.5f);
- pa->r_ave[2]=2.0f*(BLI_frand()-0.5f);
- length=VecLength(pa->r_ave);
- }
-
- pa->r_rot[0]=2.0f*(BLI_frand()-0.5f);
- pa->r_rot[1]=2.0f*(BLI_frand()-0.5f);
- pa->r_rot[2]=2.0f*(BLI_frand()-0.5f);
- pa->r_rot[3]=2.0f*(BLI_frand()-0.5f);
-
- NormalQuat(pa->r_rot);
-
if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
- /* any unique random number will do (r_ave[0]) */
- if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
+ if(ptex.exist < BLI_frand())
pa->flag |= PARS_UNEXIST;
else
pa->flag &= ~PARS_UNEXIST;
@@ -1672,10 +1628,9 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
{
//IpoCurve *icu=0; // XXX old animation system
- ParticleData *pa;
- int p, totpart=psys->totpart;
+ PARTICLE_P;
- for(p=0, pa=psys->particles; p<totpart; p++, pa++)
+ LOOP_PARTICLES
initialize_particle(pa,p,ob,psys,psmd);
if(psys->part->type != PART_FLUID) {
@@ -1743,10 +1698,39 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
- float q_phase[4];
+ float q_phase[4], length, r_phase;
part=psys->part;
ptex.ivel=1.0;
+
+ BLI_srandom(psys->seed + (pa - psys->particles));
+
+ /* we need to get every random even if they're not used so that they don't effect eachother */
+ /* while loops are to have a spherical distribution (avoid cubic distribution) */
+ length=2.0f;
+ while(length>1.0){
+ r_vel[0]=2.0f*(BLI_frand()-0.5f);
+ r_vel[1]=2.0f*(BLI_frand()-0.5f);
+ r_vel[2]=2.0f*(BLI_frand()-0.5f);
+ length=VecLength(r_vel);
+ }
+
+ length=2.0f;
+ while(length>1.0){
+ r_ave[0]=2.0f*(BLI_frand()-0.5f);
+ r_ave[1]=2.0f*(BLI_frand()-0.5f);
+ r_ave[2]=2.0f*(BLI_frand()-0.5f);
+ length=VecLength(r_ave);
+ }
+
+ r_rot[0]=2.0f*(BLI_frand()-0.5f);
+ r_rot[1]=2.0f*(BLI_frand()-0.5f);
+ r_rot[2]=2.0f*(BLI_frand()-0.5f);
+ r_rot[3]=2.0f*(BLI_frand()-0.5f);
+
+ NormalQuat(r_rot);
+
+ r_phase = BLI_frand();
if(part->from==PART_FROM_PARTICLE){
Object *tob;
@@ -1757,29 +1741,26 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
if(tob==0)
tob=ob;
- tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
+ tpsys=BLI_findlink(&tob->particlesystem, psys->target_psys-1);
state.time = pa->time;
if(pa->num == -1)
memset(&state, 0, sizeof(state));
else
psys_get_particle_state(scene, tob,tpsys,pa->num,&state,1);
- psys_get_from_key(&state,loc,nor,rot,0);
+ psys_get_from_key(&state, loc, nor, rot, 0);
- QuatMulVecf(rot,vtan);
- QuatMulVecf(rot,utan);
- VECCOPY(r_vel,pa->r_ve);
- VECCOPY(r_rot,pa->r_rot);
- VECCOPY(r_ave,pa->r_ave);
+ QuatMulVecf(rot, vtan);
+ QuatMulVecf(rot, utan);
- VECCOPY(p_vel,state.vel);
+ VECCOPY(p_vel, state.vel);
speed=Normalize(p_vel);
- VecMulf(p_vel,Inpf(pa->r_ve,p_vel));
- VECSUB(p_vel,pa->r_ve,p_vel);
+ VecMulf(p_vel, Inpf(r_vel, p_vel));
+ VECSUB(p_vel, r_vel, p_vel);
Normalize(p_vel);
- VecMulf(p_vel,speed);
+ VecMulf(p_vel, speed);
- VECCOPY(pa->fuv,loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
+ VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
}
else{
/* get precise emitter matrix if particle is born */
@@ -1833,29 +1814,25 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
/* -velocity */
if(part->randfac!=0.0){
- VECADD(r_vel,tloc,pa->r_ve);
- Mat4MulVecfl(ob->obmat,r_vel);
- VECSUB(r_vel,r_vel,loc);
+ Mat4Mul3Vecfl(ob->obmat,r_vel);
Normalize(r_vel);
}
/* -angular velocity */
if(part->avemode==PART_AVE_RAND){
- VECADD(r_ave,tloc,pa->r_ave);
- Mat4MulVecfl(ob->obmat,r_ave);
- VECSUB(r_ave,r_ave,loc);
+ Mat4Mul3Vecfl(ob->obmat,r_ave);
Normalize(r_ave);
}
/* -rotation */
if(part->randrotfac != 0.0f){
- QUATCOPY(r_rot,pa->r_rot);
Mat4ToQuat(ob->obmat,rot);
QuatMul(r_rot,r_rot,rot);
}
}
if(part->phystype==PART_PHYS_BOIDS) {
+ BoidParticle *bpa = pa->boid;
float dvec[3], q[4], mat[3][3];
VECCOPY(pa->state.co,loc);
@@ -1872,16 +1849,21 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
VECCOPY(pa->state.ave, nor);
}
/* and gravity in r_ve */
- pa->r_ve[0] = pa->r_ve[1] = 0.0f;
- pa->r_ve[2] = -1.0f;
+ bpa->gravity[0] = bpa->gravity[1] = 0.0f;
+ bpa->gravity[2] = -1.0f;
if(part->acc[2]!=0.0f)
- pa->r_ve[2] = part->acc[2];
+ bpa->gravity[2] = part->acc[2];
+
+ //pa->r_ve[0] = pa->r_ve[1] = 0.0f;
+ //pa->r_ve[2] = -1.0f;
+ //if(part->acc[2]!=0.0f)
+ // pa->r_ve[2] = part->acc[2];
/* calculate rotation matrix */
- Projf(dvec, pa->r_ve, pa->state.ave);
+ Projf(dvec, r_vel, pa->state.ave);
VecSubf(mat[0], pa->state.ave, dvec);
Normalize(mat[0]);
- VECCOPY(mat[2], pa->r_ve);
+ VECCOPY(mat[2], r_vel);
VecMulf(mat[2], -1.0f);
Normalize(mat[2]);
Crossf(mat[1], mat[2], mat[0]);
@@ -1890,10 +1872,10 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
Mat3ToQuat_is_ok(mat, q);
QuatCopy(pa->state.rot, q);
- pa->boid->health = part->boids->health;
- pa->boid->mode = eBoidMode_InAir;
- pa->boid->state_id = ((BoidState*)part->boids->states.first)->id;
- pa->boid->acc[0]=pa->boid->acc[1]=pa->boid->acc[2]=0.0f;
+ bpa->data.health = part->boids->health;
+ bpa->data.mode = eBoidMode_InAir;
+ bpa->data.state_id = ((BoidState*)part->boids->states.first)->id;
+ bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
}
else {
/* conversion done so now we apply new: */
@@ -1982,8 +1964,8 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
/* rotation phase */
phasefac = part->phasefac;
- if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */
- phasefac += part->randphasefac * pa->r_ave[0];
+ if(part->randphasefac != 0.0f)
+ phasefac += part->randphasefac * r_phase;
VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase);
/* combine base rotation & phase */
@@ -2021,8 +2003,7 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
pa->state.time = cfra;
- pa->stick_ob = 0;
- pa->flag &= ~PARS_STICKY;
+// pa->flag &= ~PARS_STICKY;
}
static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
{
@@ -2088,8 +2069,9 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSystem *kpsys = psys;
ParticleTarget *pt;
- ParticleData *pa;
- int totpart = psys->totpart, i, k, totkeys = psys->totkeyed;
+ PARTICLE_P;
+ ParticleKey *key;
+ int totpart = psys->totpart, k, totkeys = psys->totkeyed;
/* no proper targets so let's clear and bail out */
if(psys->totkeyed==0) {
@@ -2101,12 +2083,12 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
if(totpart && psys->particles->totkey != totkeys) {
free_keyed_keys(psys);
- psys->particles->keys = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
- psys->particles->totkey = totkeys;
+ key = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
- for(i=1, pa=psys->particles+1; i<totpart; i++,pa++){
- pa->keys = (pa-1)->keys + totkeys;
+ LOOP_PARTICLES {
+ pa->keys = key;
pa->totkey = totkeys;
+ key += totkeys;
}
}
@@ -2120,22 +2102,23 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
else
kpsys = BLI_findlink(&ob->particlesystem, pt->psys - 1);
- for(i=0,pa=psys->particles; i<totpart; i++, pa++) {
- (pa->keys + k)->time = -1.0; /* use current time */
+ LOOP_PARTICLES {
+ key = pa->keys + k;
+ key->time = -1.0; /* use current time */
- psys_get_particle_state(scene, pt->ob, kpsys, i%kpsys->totpart, pa->keys + k, 1);
+ psys_get_particle_state(scene, pt->ob, kpsys, p%kpsys->totpart, key, 1);
if(psys->flag & PSYS_KEYED_TIMING){
- (pa->keys+k)->time = pa->time + pt->time;
+ key->time = pa->time + pt->time;
if(pt->duration != 0.0f && k+1 < totkeys) {
- copy_particle_key(pa->keys+k+1, pa->keys+k, 1);
- (pa->keys+k+1)->time = pa->time + pt->time + pt->duration;
+ copy_particle_key(key+1, key, 1);
+ (key+1)->time = pa->time + pt->time + pt->duration;
}
}
else if(totkeys > 1)
- (pa->keys+k)->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
+ key->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
else
- pa->keys->time = pa->time;
+ key->time = pa->time;
}
if(psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f)
@@ -2269,12 +2252,12 @@ void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys)
BKE_ptcache_disk_to_mem(&pid);
}
-void psys_clear_temp_pointcache(ParticleSystem *psys)
+static void psys_clear_temp_pointcache(ParticleSystem *psys)
{
if((psys->pointcache->flag & PTCACHE_DISK_CACHE)==0)
return;
- BKE_ptache_free_mem(psys->pointcache);
+ BKE_ptcache_free_mem(&psys->pointcache->mem_cache);
}
void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra)
{
@@ -2290,16 +2273,15 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
static void update_particle_tree(ParticleSystem *psys)
{
if(psys) {
- ParticleData *pa = psys->particles;
- int p, totpart = psys->totpart;
+ PARTICLE_P;
if(!psys->tree || psys->tree_frame != psys->cfra) {
BLI_kdtree_free(psys->tree);
- psys->tree = BLI_kdtree_new(totpart);
+ psys->tree = BLI_kdtree_new(psys->totpart);
- for(p=0, pa=psys->particles; p<totpart; p++,pa++){
+ LOOP_PARTICLES {
if(pa->flag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive != PARS_ALIVE)
continue;
@@ -2542,9 +2524,9 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
ListBase *lb=&psys->effectors;
ParticleEffectorCache *ec;
ParticleSettings *part=psys->part;
- ParticleData *pa;
- float vec2[3],loc[3],*co=0;
- int p,totpart;
+ PARTICLE_P;
+ int totpart;
+ float vec2[3],loc[3],radius,*co=0;
for(ec= lb->first; ec; ec= ec->next) {
PartDeflect *pd= ec->ob->pd;
@@ -2554,7 +2536,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
&& part->phystype!=PART_PHYS_BOIDS) {
float vec[4];
- where_on_path(ec->ob, 0.0, vec, vec2);
+ where_on_path(ec->ob, 0.0, vec, vec2, NULL, &radius);
Mat4MulVecfl(ec->ob->obmat,vec);
Mat4Mul3Vecfl(ec->ob->obmat,vec2);
@@ -2562,13 +2544,15 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
QUATCOPY(ec->firstloc,vec);
VECCOPY(ec->firstdir,vec2);
+ /* TODO - use 'radius' to adjust the effector */
+
totpart=psys->totpart;
if(totpart){
ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances");
ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
- for(p=0,pa=psys->particles; p<totpart; p++, pa++){
+ LOOP_PARTICLES {
if(part->from == PART_FROM_PARTICLE) {
VECCOPY(loc, pa->fuv);
}
@@ -3247,9 +3231,10 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
/* override for boids */
if(part->phystype == PART_PHYS_BOIDS) {
+ BoidParticle *bpa = pa->boid;
radius = pa->size;
boid_z = pa->state.co[2];
- skip_ob = pa->stick_ob;
+ skip_ob = bpa->ground;
}
/* 10 iterations to catch multiple deflections */
@@ -3319,12 +3304,7 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
deflections=max_deflections;
/* store for reactors */
- copy_particle_key(&reaction_state,&pa->state,0);
-
- if(part->flag & PART_STICKY){
- pa->stick_ob=ob;
- pa->flag |= PARS_STICKY;
- }
+ copy_particle_key(&reaction_state, &pa->state, 0);
}
else {
float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
@@ -3412,7 +3392,8 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
if(part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) {
- if(pa->boid->mode == eBoidMode_OnLand || co[2] <= boid_z) {
+ BoidParticle *bpa = pa->boid;
+ if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {
co[2] = boid_z;
vel[2] = 0.0f;
}
@@ -3453,11 +3434,194 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
/************************************************/
/* Hair */
/************************************************/
-static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){
- ParticleData *pa;
+/* check if path cache or children need updating and do it if needed */
+static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
+{
+ ParticleSettings *part=psys->part;
+ ParticleEditSettings *pset=&scene->toolsettings->particle;
+ int distr=0,alloc=0,skip=0;
+
+ if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
+ alloc=1;
+
+ if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)))
+ distr=1;
+
+ if(distr){
+ if(alloc)
+ realloc_particles(ob,psys,psys->totpart);
+
+ if(get_psys_tot_child(scene, psys)) {
+ /* don't generate children while computing the hair keys */
+ if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
+ distribute_particles(scene, ob, psys, PART_FROM_CHILD);
+
+ if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
+ psys_find_parents(ob,psmd,psys);
+ }
+ }
+ }
+
+ if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
+ skip = 1; /* only hair, keyed and baked stuff can have paths */
+ else if(part->ren_as != PART_DRAW_PATH)
+ skip = 1; /* particle visualization must be set as path */
+ else if(!psys->renderdata) {
+ if(part->draw_as != PART_DRAW_REND)
+ skip = 1; /* draw visualization */
+ else if(psys->pointcache->flag & PTCACHE_BAKING)
+ skip = 1; /* no need to cache paths while baking dynamics */
+ else if(psys_in_edit_mode(scene, psys)) {
+ if((pset->flag & PE_DRAW_PART)==0)
+ skip = 1;
+ else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
+ skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */
+ }
+ }
+
+ if(!skip) {
+ psys_cache_paths(scene, ob, psys, cfra);
+
+ /* for render, child particle paths are computed on the fly */
+ if(part->childtype) {
+ if(!psys->totchild)
+ skip = 1;
+ else if((psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DONE)==0)
+ skip = 1;
+
+ if(!skip)
+ psys_cache_child_paths(scene, ob, psys, cfra, 0);
+ }
+ }
+ else if(psys->pathcache)
+ psys_free_path_cache(psys, NULL);
+}
+
+static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
+{
+ DerivedMesh *dm = psys->hair_in_dm;
+ MVert *mvert = NULL;
+ MEdge *medge = NULL;
+ MDeformVert *dvert = NULL;
HairKey *key;
+ PARTICLE_P;
+ int totpoint = 0;
+ int totedge;
+ int k;
+ float hairmat[4][4];
+
+ if(!psys->clmd) {
+ psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth);
+ psys->clmd->sim_parms->goalspring = 0.0f;
+ psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
+ psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF;
+ }
+
+ /* create a dm from hair vertices */
+ LOOP_PARTICLES
+ totpoint += pa->totkey;
+
+ totedge = totpoint - psys->totpart;
+
+ if(dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) {
+ dm->release(dm);
+ dm = psys->hair_in_dm = NULL;
+ }
+
+ if(!dm) {
+ dm = psys->hair_in_dm = CDDM_new(totpoint, totedge, 0, 0, 0);
+ DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
+ }
+
+ mvert = CDDM_get_verts(dm);
+ medge = CDDM_get_edges(dm);
+ dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
+
+ psys->clmd->sim_parms->vgroup_mass = 1;
+
+ /* make vgroup for pin roots etc.. */
+ psys->particles->hair_index = 0;
+ LOOP_PARTICLES {
+ if(p)
+ pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey;
+
+ psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, hairmat);
+
+ for(k=0, key=pa->hair; k<pa->totkey; k++,key++) {
+ VECCOPY(mvert->co, key->co);
+ Mat4MulVecfl(hairmat, mvert->co);
+ mvert++;
+
+ if(k) {
+ medge->v1 = pa->hair_index + k - 1;
+ medge->v2 = pa->hair_index + k;
+ medge++;
+ }
+
+ if(dvert) {
+ if(!dvert->totweight) {
+ dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight");
+ dvert->totweight = 1;
+ }
+
+ /* no special reason for the 0.5 */
+ /* just seems like a nice value from experiments */
+ dvert->dw->weight = k ? 0.5f : 1.0f;
+ dvert++;
+ }
+ }
+ }
+
+ if(psys->hair_out_dm)
+ psys->hair_out_dm->release(psys->hair_out_dm);
+
+ psys->clmd->point_cache = psys->pointcache;
+
+ psys->hair_out_dm = clothModifier_do(psys->clmd, scene, ob, dm, 0, 0);
+}
+static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
+{
+ ParticleSettings *part = psys->part;
+ PARTICLE_P;
+ float disp = (float)get_current_display_percentage(psys)/100.0f;
+
+ BLI_srandom(psys->seed);
+
+ LOOP_PARTICLES {
+ if(BLI_frand() > disp)
+ pa->flag |= PARS_NO_DISP;
+ else
+ pa->flag &= ~PARS_NO_DISP;
+ }
+
+ if(psys->recalc & PSYS_RECALC_RESET) {
+ /* need this for changing subsurf levels */
+ psys_calc_dmcache(ob, psmd->dm, psys);
+
+ if(psys->clmd)
+ cloth_free_modifier(ob, psys->clmd);
+ }
+
+ if(psys->effectors.first)
+ psys_end_effectors(psys);
+
+ /* dynamics with cloth simulation */
+ if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS)
+ do_hair_dynamics(scene, ob, psys, psmd);
+
+ psys_init_effectors(scene, ob, part->eff_group, psys);
+ if(psys->effectors.first)
+ precalc_effectors(scene, ob,psys,psmd,cfra);
+
+ psys_update_path_cache(scene, ob,psmd,psys,cfra);
+
+ psys->flag |= PSYS_HAIR_UPDATED;
+}
+
+static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){
+ HairKey *key, *root;
+ PARTICLE_P;
int totpart;
- int i;
Mat4Invert(ob->imat,ob->obmat);
@@ -3468,21 +3632,22 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
totpart=psys->totpart;
/* save new keys for elements if needed */
- for(i=0,pa=psys->particles; i<totpart; i++,pa++) {
+ LOOP_PARTICLES {
/* first time alloc */
if(pa->totkey==0 || pa->hair==NULL) {
pa->hair = MEM_callocN((psys->part->hair_step + 1) * sizeof(HairKey), "HairKeys");
pa->totkey = 0;
}
- key = pa->hair + pa->totkey;
+ key = root = pa->hair;
+ key += pa->totkey;
/* convert from global to geometry space */
VecCopyf(key->co, pa->state.co);
Mat4MulVecfl(ob->imat, key->co);
if(pa->totkey) {
- VECSUB(key->co, key->co, pa->hair->co);
+ VECSUB(key->co, key->co, root->co);
psys_vec_rot_to_face(psmd->dm, pa, key->co);
}
@@ -3494,7 +3659,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
/* root is always in the origin of hair space so we set it to be so after the last key is saved*/
if(pa->totkey == psys->part->hair_step + 1)
- pa->hair->co[0] = pa->hair->co[1] = pa->hair->co[2] = 0.0f;
+ root->co[0] = root->co[1] = root->co[2] = 0.0f;
}
}
/************************************************/
@@ -3504,14 +3669,14 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra,
float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size)
{
- ParticleData *pa;
ParticleSettings *part=psys->part;
KDTree *tree=0;
IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
Material *ma=give_current_material(ob,part->omat);
BoidBrainData bbd;
+ PARTICLE_P;
float timestep;
- int p, totpart;
+ int totpart;
/* current time */
float ctime, ipotime; // XXX old animation system
/* frame & time changes */
@@ -3540,7 +3705,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
if(part->type==PART_REACTOR)
vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
- for(p=0, pa=psys->particles; p<totpart; p++,pa++){
+ LOOP_PARTICLES {
if(pa->flag & PARS_UNEXIST) continue;
/* set correct ipo timing */
@@ -3609,7 +3774,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
}
/* main loop: calculate physics for all particles */
- for(p=0, pa=psys->particles; p<totpart; p++,pa++){
+ LOOP_PARTICLES {
if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
copy_particle_key(&pa->prev_state,&pa->state,1);
@@ -3697,9 +3862,6 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
else{
pa->alive=PARS_DEAD;
pa->state.time=pa->dietime;
-
- if(pa->flag&PARS_STICKY)
- psys_key_to_object(pa->stick_ob,&pa->state,0);
}
}
else
@@ -3716,116 +3878,18 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
BLI_kdtree_free(tree);
}
-/* check if path cache or children need updating and do it if needed */
-static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
-{
- ParticleSettings *part=psys->part;
- ParticleEditSettings *pset=&scene->toolsettings->particle;
- int distr=0,alloc=0;
-
- if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
- alloc=1;
-
- if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)))
- distr=1;
-
- if(distr){
- if(alloc)
- realloc_particles(ob,psys,psys->totpart);
-
- if(get_psys_tot_child(scene, psys)) {
- /* don't generate children while computing the hair keys */
- if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
- distribute_particles(scene, ob, psys, PART_FROM_CHILD);
-
- if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
- psys_find_parents(ob,psmd,psys);
- }
- }
- }
-
- if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR
- || (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){
-
- psys_cache_paths(scene, ob, psys, cfra, 0);
-
- /* for render, child particle paths are computed on the fly */
- if(part->childtype) {
- if(((psys->totchild!=0)) || (psys_in_edit_mode(scene, psys) && (pset->flag&PE_SHOW_CHILD)))
- if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE))
- psys_cache_child_paths(scene, ob, psys, cfra, 0);
- }
- }
- else if(psys->pathcache)
- psys_free_path_cache(psys);
-}
-
-/* calculate and store key locations in world coordinates */
-void psys_update_world_cos(Object *ob, ParticleSystem *psys)
-{
- ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
- ParticleData *pa;
- ParticleEditKey *key;
- int i, k, totpart;
- float hairmat[4][4];
-
- if(psys==0 || psys->edit==0)
- return;
-
- totpart= psys->totpart;
-
- for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
-
- for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++) {
- VECCOPY(key->world_co,key->co);
- Mat4MulVecfl(hairmat, key->world_co);
- }
- }
-}
-
-static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
-{
- ParticleSettings *part = psys->part;
- ParticleData *pa;
- int p;
- float disp = (float)get_current_display_percentage(psys)/50.0f-1.0f;
-
- for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
- if(pa->r_rot[0] > disp)
- pa->flag |= PARS_NO_DISP;
- else
- pa->flag &= ~PARS_NO_DISP;
- }
-
- if(psys->recalc & PSYS_RECALC_RESET)
- /* need this for changing subsurf levels */
- psys_calc_dmcache(ob, psmd->dm, psys);
-
- if(psys->effectors.first)
- psys_end_effectors(psys);
-
- psys_init_effectors(scene, ob, part->eff_group, psys);
- if(psys->effectors.first)
- precalc_effectors(scene, ob,psys,psmd,cfra);
-
- if(psys_in_edit_mode(scene, psys))
- psys_update_world_cos(ob, psys);
-
- psys_update_path_cache(scene, ob,psmd,psys,cfra);
-}
-
/* updates cached particles' alive & other flags etc..*/
static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
{
ParticleSettings *part=psys->part;
- ParticleData *pa;
ParticleKey state;
IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
Material *ma=give_current_material(ob,part->omat);
- int p;
+ PARTICLE_P;
float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra
+ BLI_srandom(psys->seed);
+
if(part->from!=PART_FROM_PARTICLE)
vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
@@ -3838,9 +3902,9 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
precalc_effectors(scene, ob,psys,psmd,cfra);
//}
- disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
+ disp= (float)get_current_display_percentage(psys)/100.0f;
- for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
+ LOOP_PARTICLES {
#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
@@ -3887,7 +3951,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
psys->lattice= NULL;
}
- if(pa->r_rot[0] > disp)
+ if(BLI_frand() > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -3938,35 +4002,35 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys)
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
}
else {
- free_hair(psys, 1);
+ free_hair(ob, psys, 1);
- CLAMP(part->path_start, part->sta, part->end + part->lifetime);
- CLAMP(part->path_end, part->sta, part->end + part->lifetime);
+ CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime));
+ CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime));
}
- psys->softflag= 0;
-
psys_reset(psys, PSYS_RESET_ALL);
}
void psys_check_boid_data(ParticleSystem *psys)
{
- ParticleData *pa = psys->particles;
- int p = 1;
+ BoidParticle *bpa;
+ PARTICLE_P;
+
+ pa = psys->particles;
if(!pa)
return;
if(psys->part && psys->part->phystype==PART_PHYS_BOIDS) {
if(!pa->boid) {
- pa->boid = MEM_callocN(psys->totpart * sizeof(BoidData), "Boid Data");
+ bpa = MEM_callocN(psys->totpart * sizeof(BoidParticle), "Boid Data");
- for(pa++; p<psys->totpart; p++, pa++)
- pa->boid = (pa-1)->boid + 1;
+ LOOP_PARTICLES
+ pa->boid = bpa++;
}
}
else if(pa->boid){
MEM_freeN(pa->boid);
- for(; p<psys->totpart; p++, pa++)
+ LOOP_PARTICLES
pa->boid = NULL;
}
}
@@ -4114,10 +4178,10 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
{
ParticleSettings *part;
- ParticleData *pa;
PointCache *cache;
PTCacheID pid;
- int totpart, oldtotpart, totchild, oldtotchild, p;
+ PARTICLE_P;
+ int totpart, oldtotpart, totchild, oldtotchild;
float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
int framenr, framedelta, startframe, endframe;
@@ -4129,7 +4193,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
framedelta= framenr - cache->simframe;
/* set suitable cache range automatically */
- if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0)
+ if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0 && !(psys->flag & PSYS_HAIR_DYNAMICS))
psys_get_pointcache_start_end(scene, psys, &cache->startframe, &cache->endframe);
BKE_ptcache_id_from_particles(&pid, ob, psys);
@@ -4260,7 +4324,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
}
else if(result==PTCACHE_READ_OLD) {
psys->cfra = (float)cache->simframe;
- for(p=0, pa=psys->particles; p<totpart; p++, pa++) {
+ LOOP_PARTICLES {
/* update alive status */
if(pa->time > psys->cfra)
pa->alive = PARS_UNBORN;
@@ -4299,10 +4363,11 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
}
/* set particles to be not calculated TODO: can't work with pointcache */
- disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
+ disp= (float)get_current_display_percentage(psys)/100.0f;
- for(p=0, pa=psys->particles; p<totpart; p++,pa++){
- if(pa->r_rot[0] > disp)
+ BLI_srandom(psys->seed);
+ LOOP_PARTICLES {
+ if(BLI_frand() > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -4339,7 +4404,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
psys_update_path_cache(scene, ob, psmd, psys,(int)cfra);
}
else if(psys->pathcache)
- psys_free_path_cache(psys);
+ psys_free_path_cache(psys, NULL);
/* cleanup */
if(vg_vel) MEM_freeN(vg_vel);
@@ -4353,39 +4418,9 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
}
}
-static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys)
-{
- SoftBody *sb;
- short softflag;
-
- if(!(psys->softflag & OB_SB_ENABLE))
- return;
-
- /* let's replace the object's own softbody with the particle softbody */
- /* a temporary solution before cloth simulation is implemented, jahka */
-
- /* save these */
- sb= ob->soft;
- softflag= ob->softflag;
-
- /* swich to new ones */
- ob->soft= psys->soft;
- ob->softflag= psys->softflag;
-
- /* do softbody */
- sbObjectStep(scene, ob, (float)scene->r.cfra, NULL, psys_count_keys(psys));
-
- /* return things back to normal */
- psys->soft= ob->soft;
- psys->softflag= ob->softflag;
-
- ob->soft= sb;
- ob->softflag= softflag;
-}
-
static int hair_needs_recalc(ParticleSystem *psys)
{
- if((psys->flag & PSYS_EDITED)==0 &&
+ if(!(psys->flag & PSYS_EDITED) && (!psys->edit || !psys->edit->edited) &&
((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_RESET)) {
return 1;
}
@@ -4426,7 +4461,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
float hcfra=0.0f;
int i;
- free_hair(psys, 0);
+ free_hair(ob, psys, 0);
/* first step is negative so particles get killed and reset */
psys->cfra= 1.0f;
@@ -4440,10 +4475,6 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
psys->flag |= PSYS_HAIR_DONE;
}
- /* handle softbody hair */
- if(psys->part->type==PART_HAIR && psys->soft)
- psys_to_softbody(scene, ob, psys);
-
/* the main particle system step */
system_step(scene, ob, psys, psmd, cfra);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 69da8f19d8c..d685bc29568 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -67,23 +67,13 @@
/* needed for directory lookup */
+/* untitled blend's need getpid for a unique name */
#ifndef WIN32
#include <dirent.h>
+#include <unistd.h>
#else
- #include "BLI_winstuff.h"
-#endif
-
-/* untitled blend's need getpid for a unique name */
-#ifdef WIN32
#include <process.h>
-#else
-#include <unistd.h>
-#endif
-
-#ifdef _WIN32
-#ifndef snprintf
-#define snprintf _snprintf
-#endif
+ #include "BLI_winstuff.h"
#endif
static void ptcache_data_to(void **data, int type, int index, void *to);
@@ -181,6 +171,7 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
{
ParticleSystem *psys= psys_v;
ParticleData *pa = psys->particles + index;
+ BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
float times[3] = {pa->time, pa->dietime, pa->lifetime};
if(data[BPHYS_DATA_INDEX]) {
@@ -198,8 +189,8 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
ptcache_data_from(data, BPHYS_DATA_SIZE, &pa->size);
ptcache_data_from(data, BPHYS_DATA_TIMES, times);
- if(pa->boid)
- ptcache_data_from(data, BPHYS_DATA_TIMES, &pa->boid);
+ if(boid)
+ ptcache_data_from(data, BPHYS_DATA_BOIDS, &boid->data);
return 1;
}
@@ -215,6 +206,7 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
{
ParticleSystem *psys= psys_v;
ParticleData *pa = psys->particles + index;
+ BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
if(cfra > pa->state.time)
memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey));
@@ -238,8 +230,8 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
pa->lifetime = times[2];
}
- if(pa->boid)
- ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &pa->boid);
+ if(boid)
+ ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &boid->data);
/* determine velocity from previous location */
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
@@ -390,8 +382,6 @@ static int ptcache_totpoint_cloth(void *cloth_v)
/* Creating ID's */
void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
{
- ParticleSystemModifierData *psmd;
-
memset(pid, 0, sizeof(PTCacheID));
pid->ob= ob;
@@ -414,12 +404,7 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY);
pid->info_types= 0;
- if(sb->particles) {
- psmd= psys_get_modifier(ob, sb->particles);
- // pid->stack_index= modifiers_indexInObject(ob, (ModifierData*)psmd); XXX TODO - get other index DG
- }
- else
- pid->stack_index = pid->cache->index;
+ pid->stack_index = pid->cache->index;
}
void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *psys)
@@ -434,6 +419,9 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
pid->cache_ptr= &psys->pointcache;
pid->ptcaches= &psys->ptcaches;
+ if(psys->part->type != PART_HAIR)
+ pid->flag |= PTCACHE_VEL_PER_SEC;
+
pid->write_elem= ptcache_write_particle;
pid->write_stream = NULL;
pid->read_stream = NULL;
@@ -477,6 +465,19 @@ static int ptcache_totpoint_smoke(void *smoke_v)
return 0;
}
+/* Smoke functions */
+static int ptcache_totpoint_smoke_turbulence(void *smoke_v)
+{
+ SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
+ SmokeDomainSettings *sds = smd->domain;
+
+ if(sds->wt) {
+ return sds->res_wt[0]*sds->res_wt[1]*sds->res_wt[2];
+ }
+ else
+ return 0;
+}
+
// forward decleration
static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size);
@@ -527,7 +528,7 @@ static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned i
}
static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
-{
+{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
@@ -541,7 +542,7 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
- ptcache_compress_write(pf, (unsigned char *)sds->view3d, in_len*4, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)sds->shadow, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)dens, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)densold, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)heat, in_len, out, mode);
@@ -560,36 +561,36 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
return 1;
}
-
return 0;
}
-/*
static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
if(sds->wt) {
- unsigned int res_big[3];
- size_t res = sds->res[0]*sds->res[1]*sds->res[2];
+ int res_big_array[3];
+ int res_big;
+ int res = sds->res[0]*sds->res[1]*sds->res[2];
float *dens, *densold, *tcu, *tcv, *tcw;
unsigned int in_len = sizeof(float)*(unsigned int)res;
- unsigned int in_len_big = sizeof(float) * (unsigned int)res_big;
+ unsigned int in_len_big;
unsigned char *out;
int mode;
- smoke_turbulence_get_res(sds->wt, res_big);
- mode = res_big[0]*res_big[1]*res_big[2] >= 1000000 ? 2 : 1;
+ smoke_turbulence_get_res(sds->wt, res_big_array);
+ res_big = res_big_array[0]*res_big_array[1]*res_big_array[2];
+ mode = res_big >= 1000000 ? 2 : 1;
+ in_len_big = sizeof(float) * (unsigned int)res_big;
smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer");
-
ptcache_compress_write(pf, (unsigned char *)dens, in_len_big, out, mode);
ptcache_compress_write(pf, (unsigned char *)densold, in_len_big, out, mode);
-
MEM_freeN(out);
+
out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
ptcache_compress_write(pf, (unsigned char *)tcu, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)tcv, in_len, out, mode);
@@ -600,7 +601,6 @@ static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
}
return 0;
}
-*/
// forward decleration
static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, int size);
@@ -655,7 +655,7 @@ static void ptcache_read_smoke(PTCacheFile *pf, void *smoke_v)
smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
- ptcache_compress_read(pf, (unsigned char *)sds->view3d, out_len*4);
+ ptcache_compress_read(pf, (unsigned char *)sds->shadow, out_len);
ptcache_compress_read(pf, (unsigned char*)dens, out_len);
ptcache_compress_read(pf, (unsigned char*)densold, out_len);
ptcache_compress_read(pf, (unsigned char*)heat, out_len);
@@ -672,26 +672,32 @@ static void ptcache_read_smoke(PTCacheFile *pf, void *smoke_v)
}
}
-/*
static void ptcache_read_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
if(sds->fluid) {
- unsigned int res[3];
+ int res = sds->res[0]*sds->res[1]*sds->res[2];
+ int res_big, res_big_array[3];
float *dens, *densold, *tcu, *tcv, *tcw;
unsigned int out_len = sizeof(float)*(unsigned int)res;
+ unsigned int out_len_big;
- smoke_turbulence_get_res(sds->wt, res);
+ smoke_turbulence_get_res(sds->wt, res_big_array);
+ res_big = res_big_array[0]*res_big_array[1]*res_big_array[2];
+ out_len_big = sizeof(float) * (unsigned int)res_big;
smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
- ptcache_compress_read(pf, (unsigned char*)dens, out_len);
-
+ ptcache_compress_read(pf, (unsigned char*)dens, out_len_big);
+ ptcache_compress_read(pf, (unsigned char*)densold, out_len_big);
+
+ ptcache_compress_read(pf, (unsigned char*)tcu, out_len);
+ ptcache_compress_read(pf, (unsigned char*)tcv, out_len);
+ ptcache_compress_read(pf, (unsigned char*)tcw, out_len);
}
}
-*/
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd)
{
@@ -722,7 +728,7 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
pid->write_header= ptcache_write_basic_header;
pid->read_header= ptcache_read_basic_header;
- pid->data_types= (1<<BPHYS_DATA_LOCATION); // bogus values tot make pointcache happy
+ pid->data_types= (1<<BPHYS_DATA_LOCATION); // bogus values to make pointcache happy
pid->info_types= 0;
}
@@ -742,13 +748,13 @@ void BKE_ptcache_id_from_smoke_turbulence(PTCacheID *pid, struct Object *ob, str
pid->cache_ptr= &sds->point_cache[1];
pid->ptcaches= &sds->ptcaches[1];
- pid->totpoint= pid->totwrite= ptcache_totpoint_smoke;
+ pid->totpoint= pid->totwrite= ptcache_totpoint_smoke_turbulence;
pid->write_elem= NULL;
pid->read_elem= NULL;
- pid->read_stream = ptcache_read_smoke;
- pid->write_stream = ptcache_write_smoke;
+ pid->read_stream = ptcache_read_smoke_turbulence;
+ pid->write_stream = ptcache_write_smoke_turbulence;
pid->interpolate_elem= NULL;
@@ -800,13 +806,9 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
- BKE_ptcache_id_from_particles(pid, ob, psys);
- BLI_addtail(lb, pid);
-
- if(psys->soft) {
+ if(psys->part) {
pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
- BKE_ptcache_id_from_softbody(pid, ob, psys->soft);
+ BKE_ptcache_id_from_particles(pid, ob, psys);
BLI_addtail(lb, pid);
}
}
@@ -824,6 +826,10 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md);
BLI_addtail(lb, pid);
+
+ pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_smoke_turbulence(pid, ob, (SmokeModifierData*)md);
+ BLI_addtail(lb, pid);
}
}
}
@@ -1087,7 +1093,7 @@ static void ptcache_file_init_pointers(PTCacheFile *pf)
pf->cur[BPHYS_DATA_BOIDS] = data_types & (1<<BPHYS_DATA_BOIDS) ? &pf->data.boids : NULL;
}
-static void ptcache_mem_init_pointers(PTCacheMem *pm)
+void BKE_ptcache_mem_init_pointers(PTCacheMem *pm)
{
int data_types = pm->data_types;
int i;
@@ -1096,7 +1102,7 @@ static void ptcache_mem_init_pointers(PTCacheMem *pm)
pm->cur[i] = data_types & (1<<i) ? pm->data[i] : NULL;
}
-static void ptcache_mem_incr_pointers(PTCacheMem *pm)
+void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
{
int i;
@@ -1249,12 +1255,12 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
return 0;
if(pm) {
- ptcache_mem_init_pointers(pm);
+ BKE_ptcache_mem_init_pointers(pm);
totpoint = pm->totpoint;
index = pm->data_types & (1<<BPHYS_DATA_INDEX) ? pm->cur[BPHYS_DATA_INDEX] : &i;
}
if(pm2) {
- ptcache_mem_init_pointers(pm2);
+ BKE_ptcache_mem_init_pointers(pm2);
totpoint2 = pm2->totpoint;
index2 = pm2->data_types & (1<<BPHYS_DATA_INDEX) ? pm2->cur[BPHYS_DATA_INDEX] : &i;
}
@@ -1336,7 +1342,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
if(pm) {
- ptcache_mem_incr_pointers(pm);
+ BKE_ptcache_mem_incr_pointers(pm);
index = pm->data_types & (1<<BPHYS_DATA_INDEX) ? pm->cur[BPHYS_DATA_INDEX] : &i;
}
}
@@ -1387,7 +1393,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
if(pm2) {
- ptcache_mem_incr_pointers(pm2);
+ BKE_ptcache_mem_incr_pointers(pm2);
index2 = pm2->data_types & (1<<BPHYS_DATA_INDEX) ? pm2->cur[BPHYS_DATA_INDEX] : &i;
}
}
@@ -1559,11 +1565,11 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
pm->data_types = cfra ? pid->data_types : pid->info_types;
ptcache_alloc_data(pm);
- ptcache_mem_init_pointers(pm);
+ BKE_ptcache_mem_init_pointers(pm);
for(i=0; i<totpoint; i++) {
if(pid->write_elem && pid->write_elem(i, pid->calldata, pm->cur))
- ptcache_mem_incr_pointers(pm);
+ BKE_ptcache_mem_incr_pointers(pm);
}
//ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
@@ -1664,6 +1670,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
PTCacheMem *pm= pid->cache->mem_cache.first;
PTCacheMem *link= NULL;
+ pm= pid->cache->mem_cache.first;
+
if(mode == PTCACHE_CLEAR_ALL) {
pid->cache->last_exact = 0;
for(; pm; pm=pm->next)
@@ -1808,9 +1816,10 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
else if(mode == PTCACHE_RESET_OUTDATED) {
reset = 1;
- if(cache->flag & PTCACHE_OUTDATED)
- if(!(cache->flag & PTCACHE_BAKED))
- clear= 1;
+ if(cache->flag & PTCACHE_OUTDATED && !(cache->flag & PTCACHE_BAKED)) {
+ clear= 1;
+ cache->flag &= ~PTCACHE_OUTDATED;
+ }
}
if(reset) {
@@ -1826,6 +1835,8 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH);
else if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
smokeModifier_reset(pid->calldata);
+ else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES)
+ smokeModifier_reset_turbulence(pid->calldata);
}
if(clear)
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
@@ -1851,10 +1862,10 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- /* Baked softbody hair has to be checked first, because we don't want to reset */
- /* particles or softbody in that case -jahka */
- if(psys->soft) {
- BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
+ /* Baked cloth hair has to be checked first, because we don't want to reset */
+ /* particles or cloth in that case -jahka */
+ if(psys->clmd) {
+ BKE_ptcache_id_from_cloth(&pid, ob, psys->clmd);
if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED)))
reset |= BKE_ptcache_id_reset(scene, &pid, mode);
else
@@ -1863,7 +1874,7 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
else if(psys->recalc & PSYS_RECALC_REDO || psys->recalc & PSYS_RECALC_CHILD)
skip = 1;
- if(skip == 0) {
+ if(skip == 0 && psys->part) {
BKE_ptcache_id_from_particles(&pid, ob, psys);
reset |= BKE_ptcache_id_reset(scene, &pid, mode);
}
@@ -1880,6 +1891,9 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
{
BKE_ptcache_id_from_smoke(&pid, ob, (SmokeModifierData*)md);
reset |= BKE_ptcache_id_reset(scene, &pid, mode);
+
+ BKE_ptcache_id_from_smoke_turbulence(&pid, ob, (SmokeModifierData*)md);
+ reset |= BKE_ptcache_id_reset(scene, &pid, mode);
}
}
}
@@ -1941,7 +1955,7 @@ void BKE_ptcache_set_continue_physics(Scene *scene, int enable)
if(CONTINUE_PHYSICS == 0) {
for(ob=G.main->object.first; ob; ob=ob->id.next)
if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
}
}
}
@@ -1968,9 +1982,9 @@ PointCache *BKE_ptcache_add(ListBase *ptcaches)
return cache;
}
-void BKE_ptache_free_mem(PointCache *cache)
+void BKE_ptcache_free_mem(ListBase *mem_cache)
{
- PTCacheMem *pm = cache->mem_cache.first;
+ PTCacheMem *pm = mem_cache->first;
if(pm) {
for(; pm; pm=pm->next) {
@@ -1979,22 +1993,25 @@ void BKE_ptache_free_mem(PointCache *cache)
MEM_freeN(pm->index_array);
}
- BLI_freelistN(&cache->mem_cache);
+ BLI_freelistN(mem_cache);
}
}
void BKE_ptcache_free(PointCache *cache)
{
- BKE_ptache_free_mem(cache);
+ BKE_ptcache_free_mem(&cache->mem_cache);
+ if(cache->edit && cache->free_edit)
+ cache->free_edit(cache->edit);
MEM_freeN(cache);
}
void BKE_ptcache_free_list(ListBase *ptcaches)
{
PointCache *cache = ptcaches->first;
- for(; cache; cache=cache->next)
- BKE_ptache_free_mem(cache);
-
- BLI_freelistN(ptcaches);
+ while(cache) {
+ BLI_remlink(ptcaches, cache);
+ BKE_ptcache_free(cache);
+ cache = ptcaches->first;
+ }
}
static PointCache *ptcache_copy(PointCache *cache)
@@ -2102,6 +2119,25 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
if((cache->flag & PTCACHE_BAKED)==0) {
if(pid->type==PTCACHE_TYPE_PARTICLES)
psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe);
+ else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) {
+ /* get all pids from the object and search for smoke low res */
+ ListBase pidlist2;
+ PTCacheID *pid2;
+ BKE_ptcache_ids_from_object(&pidlist2, pid->ob);
+ for(pid2=pidlist2.first; pid2; pid2=pid2->next) {
+ if(pid2->type == PTCACHE_TYPE_SMOKE_DOMAIN)
+ {
+ if(pid2->cache && !(pid2->cache->flag & PTCACHE_BAKED)) {
+ if(bake || pid2->cache->flag & PTCACHE_REDO_NEEDED)
+ BKE_ptcache_id_clear(pid2, PTCACHE_CLEAR_ALL, 0);
+ if(bake) {
+ pid2->cache->flag |= PTCACHE_BAKING;
+ pid2->cache->flag &= ~PTCACHE_BAKED;
+ }
+ }
+ }
+ }
+ }
if(bake || cache->flag & PTCACHE_REDO_NEEDED)
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
@@ -2258,7 +2294,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
pm->frame = cfra;
ptcache_alloc_data(pm);
- ptcache_mem_init_pointers(pm);
+ BKE_ptcache_mem_init_pointers(pm);
ptcache_file_init_pointers(pf);
for(i=0; i<pm->totpoint; i++) {
@@ -2274,7 +2310,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
return;
}
ptcache_copy_data(pf->cur, pm->cur);
- ptcache_mem_incr_pointers(pm);
+ BKE_ptcache_mem_incr_pointers(pm);
}
//ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
@@ -2305,7 +2341,7 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
pf->totpoint = pm->totpoint;
pf->type = pid->type;
- ptcache_mem_init_pointers(pm);
+ BKE_ptcache_mem_init_pointers(pm);
ptcache_file_init_pointers(pf);
if(!ptcache_file_write_header_begin(pf) || !pid->write_header(pf)) {
@@ -2325,7 +2361,7 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
ptcache_file_close(pf);
return;
}
- ptcache_mem_incr_pointers(pm);
+ BKE_ptcache_mem_incr_pointers(pm);
}
ptcache_file_close(pf);
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 139895bbdaf..de2118af202 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -52,30 +52,6 @@
#include "BKE_blender.h"
#include "BKE_sca.h"
-//#include "wm_event_types.h"
-
-void free_text_controllers(Text *txt)
-{
- Object *ob;
- bController *cont;
-
- ob= G.main->object.first;
- while(ob) {
- cont= ob->controllers.first;
- while(cont) {
- if(cont->type==CONT_PYTHON) {
- bPythonCont *pc;
-
- pc= cont->data;
- if(pc->text==txt) pc->text= NULL;
- }
- cont= cont->next;
- }
- ob= ob->id.next;
- }
-}
-
-
/* ******************* SENSORS ************************ */
void free_sensor(bSensor *sens)
@@ -418,12 +394,10 @@ void init_actuator(bActuator *act)
act->data= 0;
switch(act->type) {
-#ifdef __NLA
case ACT_ACTION:
case ACT_SHAPEACTION:
act->data= MEM_callocN(sizeof(bActionActuator), "actionact");
break;
-#endif
case ACT_SOUND:
sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
sa->volume = 1.0f;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 6dd362d15a8..6f9ed3e0978 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -245,6 +245,11 @@ void free_scene(Scene *sce)
base= base->next;
}
/* do not free objects! */
+
+ if(sce->gpd) {
+ sce->gpd->id.us--;
+ sce->gpd= NULL;
+ }
BLI_freelistN(&sce->base);
seq_free_editing(sce);
@@ -399,11 +404,13 @@ Scene *add_scene(char *name)
sce->unit.scale_length = 1.0f;
pset= &sce->toolsettings->particle;
- pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER;
+ pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER|PE_AUTO_VELOCITY;
pset->emitterdist= 0.25f;
pset->totrekey= 5;
pset->totaddkey= 5;
pset->brushtype= PE_BRUSH_NONE;
+ pset->draw_step= 2;
+ pset->fade_frames= 2;
for(a=0; a<PE_TOT_BRUSH; a++) {
pset->brush[a].strength= 50;
pset->brush[a].size= 50;
@@ -853,14 +860,3 @@ float get_render_aosss_error(RenderData *r, float error)
return error;
}
-void free_dome_warp_text(struct Text *txt)
-{
- Scene *scene;
-
- scene = G.main->scene.first;
- while(scene) {
- if (scene->r.dometext == txt)
- scene->r.dometext = NULL;
- scene = scene->id.next;
- }
-}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index cc740d7fb3d..661d0da1550 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -33,8 +33,10 @@
#include "MEM_guardedalloc.h"
+#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
#include "BLI_blenlib.h"
@@ -321,4 +323,23 @@ void free_screen(bScreen *sc)
BLI_freelistN(&sc->areabase);
}
+/* for depsgraph */
+unsigned int BKE_screen_visible_layers(bScreen *screen)
+{
+ ScrArea *sa;
+ unsigned int layer= 0;
+
+ if(!screen)
+ return layer;
+
+ /* get all used view3d layers */
+ for(sa= screen->areabase.first; sa; sa= sa->next)
+ if(sa->spacetype==SPACE_VIEW3D)
+ layer |= ((View3D *)sa->spacedata.first)->lay;
+
+ if(!layer)
+ return screen->scene->lay;
+
+ return layer;
+}
diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c
index 159a60ad3af..7f3e2789232 100644
--- a/source/blender/blenkernel/intern/sequence.c
+++ b/source/blender/blenkernel/intern/sequence.c
@@ -127,7 +127,7 @@ void new_tstripdata(Sequence *seq)
/* free */
-void free_proxy_seq(Sequence *seq)
+static void free_proxy_seq(Sequence *seq)
{
if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
IMB_free_anim(seq->strip->proxy->anim);
@@ -570,7 +570,7 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
}
seq->strip->len = seq->len;
} else if (seq->type == SEQ_SOUND) {
- seq->len = AUD_getInfo(seq->sound->snd_sound).length * FPS;
+ seq->len = AUD_getInfo(seq->sound->handle).length * FPS;
seq->len -= seq->anim_startofs;
seq->len -= seq->anim_endofs;
if (seq->len < 0) {
@@ -682,7 +682,7 @@ void clear_scene_in_allseqs(Scene *sce)
}
}
-char *give_seqname_by_type(int type)
+static char *give_seqname_by_type(int type)
{
switch(type) {
case SEQ_META: return "Meta";
@@ -949,7 +949,7 @@ static TStripElem* alloc_tstripdata(int len, const char * name)
return se;
}
-TStripElem *give_tstripelem(Sequence *seq, int cfra)
+static TStripElem *give_tstripelem(Sequence *seq, int cfra)
{
TStripElem *se;
int nr;
@@ -1297,7 +1297,7 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
se->ibuf = 0;
}
-void seq_proxy_rebuild(Scene *scene, Sequence * seq)
+static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
{
int cfra;
float rsize = seq->strip->proxy->size;
@@ -2623,7 +2623,7 @@ ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown
}
/* check used when we need to change seq->blend_mode but not to effect or audio strips */
-int seq_can_blend(Sequence *seq)
+static int seq_can_blend(Sequence *seq)
{
if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
return 1;
@@ -2749,7 +2749,7 @@ static void *seq_prefetch_thread(void * This_)
return 0;
}
-void seq_start_threads(Scene *scene)
+static void seq_start_threads(Scene *scene)
{
int i;
@@ -2782,7 +2782,7 @@ void seq_start_threads(Scene *scene)
BLI_init_threads(0, 0, 0);
}
-void seq_stop_threads()
+static void seq_stop_threads()
{
PrefetchThread *tslot;
PrefetchQueueElem *e;
@@ -2850,7 +2850,7 @@ void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
pthread_mutex_unlock(&wakeup_lock);
}
-void seq_wait_for_prefetch_ready()
+static void seq_wait_for_prefetch_ready()
{
PrefetchThread *tslot;
@@ -2984,7 +2984,7 @@ static void free_anim_seq(Sequence *seq)
}
}
-void free_imbuf_seq_except(Scene *scene, int cfra)
+static void free_imbuf_seq_except(Scene *scene, int cfra)
{
Editing *ed= seq_give_editing(scene, FALSE);
Sequence *seq;
@@ -3178,7 +3178,7 @@ void free_imbuf_seq()
}
#endif
-void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
+static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
{
/* force update of all sequences with this ipo, on ipo changes */
Editing *ed= seq_give_editing(scene, FALSE);
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 577156ef453..92c586f0001 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -575,7 +575,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object
}
}
- //Just to make sure we are not letting any memory behind
+ //Just to make sure we are not leaving any memory behind
assert(ssmd.emCache == NULL);
assert(ssmd.mCache == NULL);
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 91de57024e6..fea62ea1f21 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -38,6 +38,7 @@
#include <float.h>
#include <math.h>
#include "stdio.h"
+#include "string.h" /* memset */
#include "BLI_linklist.h"
#include "BLI_rand.h"
@@ -92,10 +93,10 @@ static void tend ( void )
{
QueryPerformanceCounter ( &liCurrentTime );
}
-//static double tval()
-//{
-// return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart ));
-//}
+static double tval()
+{
+ return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart ));
+}
#else
#include <sys/time.h>
static struct timeval _tstart, _tend;
@@ -125,7 +126,6 @@ struct SmokeModifierData;
// forward declerations
static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct);
void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len);
-void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light);
#define TRI_UVOFFSET (1./4.)
@@ -167,6 +167,9 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
// calc other res with max_res provided
VECSUB(size, max, min);
+ // printf("size: %f, %f, %f\n", size[0], size[1], size[2]);
+
+ // prevent crash when initializing a plane as domain
if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
return 0;
@@ -209,28 +212,36 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
}
}
+ // printf("smd->domain->dx: %f\n", smd->domain->dx);
+
// TODO: put in failsafe if res<=0 - dg
// printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
// dt max is 0.1
smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, 0.1);
smd->time = scene->r.cfra;
- smd->domain->firstframe = smd->time;
-
- if(!smd->domain->wt && (smd->domain->flags & MOD_SMOKE_HIGHRES))
- {
- smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise);
- smoke_turbulence_initBlenderRNA(smd->domain->wt, &smd->domain->strength);
- }
- if(!smd->domain->view3d)
+ if(smd->domain->flags & MOD_SMOKE_HIGHRES)
{
- // TVox is for transparency
- smd->domain->view3d = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2]*4, "Smoke_tVox");
+ smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise);
+ smd->domain->res_wt[0] = smd->domain->res[0] * (smd->domain->amplify + 1);
+ smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1);
+ smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1);
+ smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1);
+ // printf("smd->domain->amplify: %d\n", smd->domain->amplify);
+ // printf("(smd->domain->flags & MOD_SMOKE_HIGHRES)\n");
}
+ if(!smd->domain->shadow)
+ smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow");
+
smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta));
+ if(smd->domain->wt)
+ {
+ smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength));
+ // printf("smoke_initWaveletBlenderRNA\n");
+ }
return 1;
}
else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow)
@@ -270,13 +281,11 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
SmokeCollSettings *scs = smd->coll;
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getTessFaceArray(dm);
- size_t i = 0;
- int divs = 0;
+ int i = 0, divs = 0;
int *tridivs = NULL;
float cell_len = 1.0 / 50.0; // for res = 50
- size_t newdivs = 0;
- //size_t max_points = 0;
- size_t quads = 0, facecounter = 0;
+ int newdivs = 0;
+ int quads = 0, facecounter = 0;
// copy obmat
Mat4CpyMat4(scs->mat, ob->obmat);
@@ -314,7 +323,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
int again = 0;
do
{
- size_t j, k;
+ int j, k;
int divs1 = tridivs[3 * facecounter + 0];
int divs2 = tridivs[3 * facecounter + 1];
//int divs3 = tridivs[3 * facecounter + 2];
@@ -409,7 +418,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
if(!smd->coll->bvhtree)
{
- smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
+ smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getTessFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
}
return 1;
}
@@ -517,13 +526,13 @@ void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *faces, int
}
}
-void smokeModifier_freeDomain(SmokeModifierData *smd)
+static void smokeModifier_freeDomain(SmokeModifierData *smd)
{
if(smd->domain)
{
- // free visualisation buffers
- if(smd->domain->view3d)
- MEM_freeN(smd->domain->view3d);
+ if(smd->domain->shadow)
+ MEM_freeN(smd->domain->shadow);
+ smd->domain->shadow = NULL;
if(smd->domain->fluid)
smoke_free(smd->domain->fluid);
@@ -541,7 +550,7 @@ void smokeModifier_freeDomain(SmokeModifierData *smd)
}
}
-void smokeModifier_freeFlow(SmokeModifierData *smd)
+static void smokeModifier_freeFlow(SmokeModifierData *smd)
{
if(smd->flow)
{
@@ -558,7 +567,7 @@ void smokeModifier_freeFlow(SmokeModifierData *smd)
}
}
-void smokeModifier_freeCollision(SmokeModifierData *smd)
+static void smokeModifier_freeCollision(SmokeModifierData *smd)
{
if(smd->coll)
{
@@ -583,17 +592,24 @@ void smokeModifier_freeCollision(SmokeModifierData *smd)
}
}
+void smokeModifier_reset_turbulence(struct SmokeModifierData *smd)
+{
+ if(smd && smd->domain && smd->domain->wt)
+ {
+ smoke_turbulence_free(smd->domain->wt);
+ smd->domain->wt = NULL;
+ }
+}
+
void smokeModifier_reset(struct SmokeModifierData *smd)
{
if(smd)
{
if(smd->domain)
{
- if(smd->domain->view3d)
- MEM_freeN(smd->domain->view3d);
- smd->domain->view3d = NULL;
-
- smd->domain->tex = NULL;
+ if(smd->domain->shadow)
+ MEM_freeN(smd->domain->shadow);
+ smd->domain->shadow = NULL;
if(smd->domain->fluid)
{
@@ -601,23 +617,14 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
smd->domain->fluid = NULL;
}
- if(smd->domain->wt)
- {
- smoke_turbulence_free(smd->domain->wt);
- smd->domain->wt = NULL;
- }
-
- smd->domain->point_cache[0]->flag &= ~PTCACHE_SIMULATION_VALID;
smd->domain->point_cache[0]->flag |= PTCACHE_OUTDATED;
- smd->domain->point_cache[0]->simframe= 0;
- smd->domain->point_cache[0]->last_exact= 0;
-
- smd->domain->point_cache[1]->flag &= ~PTCACHE_SIMULATION_VALID;
smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
- smd->domain->point_cache[1]->simframe= 0;
- smd->domain->point_cache[1]->last_exact= 0;
- // printf("reset_domain\n");
+ smokeModifier_reset_turbulence(smd);
+
+ smd->time = -1;
+
+ // printf("reset domain end\n");
}
else if(smd->flow)
{
@@ -626,7 +633,7 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
{
free_bvhtree_from_mesh(smd->flow->bvh);
MEM_freeN(smd->flow->bvh);
- }
+ }
smd->flow->bvh = NULL;
*/
}
@@ -685,22 +692,21 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
/* set some standard values */
smd->domain->fluid = NULL;
+ smd->domain->wt = NULL;
smd->domain->eff_group = NULL;
smd->domain->fluid_group = NULL;
smd->domain->coll_group = NULL;
smd->domain->maxres = 32;
+ smd->domain->amplify = 1;
+ smd->domain->omega = 1.0;
smd->domain->alpha = -0.001;
smd->domain->beta = 0.1;
smd->domain->flags = MOD_SMOKE_DISSOLVE_LOG;
- smd->domain->diss_speed = 5;
- smd->domain->strength = 2.0f;
- smd->domain->amplify = 1;
+ smd->domain->strength = 2.0;
smd->domain->noise = MOD_SMOKE_NOISEWAVE;
- smd->domain->wt = NULL;
-
+ smd->domain->diss_speed = 5;
// init 3dview buffer
- smd->domain->view3d = NULL;
- smd->domain->tex = NULL;
+ smd->domain->viewsettings = 0;
}
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
{
@@ -734,15 +740,320 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
}
}
-// forward declaration
-void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm);
+// forward decleration
+static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct);
+static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
+static int get_lamp(Scene *scene, float *light)
+{
+ Base *base_tmp = NULL;
+ for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
+ {
+ if(base_tmp->object->type == OB_LAMP)
+ {
+ Lamp *la = (Lamp *)base_tmp->object->data;
+
+ if(la->type == LA_LOCAL)
+ {
+ VECCOPY(light, base_tmp->object->obmat[3]);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
+{
+ SmokeDomainSettings *sds = smd->domain;
+ GroupObject *go = NULL;
+ Base *base = NULL;
+
+ // do flows and fluids
+ if(1)
+ {
+ Object *otherobj = NULL;
+ ModifierData *md = NULL;
+ if(sds->fluid_group) // we use groups since we have 2 domains
+ go = sds->fluid_group->gobject.first;
+ else
+ base = scene->base.first;
+ while(base || go)
+ {
+ otherobj = NULL;
+ if(sds->fluid_group)
+ {
+ if(go->ob)
+ otherobj = go->ob;
+ }
+ else
+ otherobj = base->object;
+ if(!otherobj)
+ {
+ if(sds->fluid_group)
+ go = go->next;
+ else
+ base= base->next;
+
+ continue;
+ }
+
+ md = modifiers_findByType(otherobj, eModifierType_Smoke);
+
+ // check for active smoke modifier
+ if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+ {
+ SmokeModifierData *smd2 = (SmokeModifierData *)md;
+
+ // check for initialized smoke object
+ if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
+ {
+ // we got nice flow object
+ SmokeFlowSettings *sfs = smd2->flow;
+
+ if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
+ {
+ ParticleSystem *psys = sfs->psys;
+ ParticleSettings *part=psys->part;
+ ParticleData *pa = NULL;
+ int p = 0;
+ float *density = smoke_get_density(sds->fluid);
+ float *bigdensity = smoke_turbulence_get_density(sds->wt);
+ float *heat = smoke_get_heat(sds->fluid);
+ float *velocity_x = smoke_get_velocity_x(sds->fluid);
+ float *velocity_y = smoke_get_velocity_y(sds->fluid);
+ float *velocity_z = smoke_get_velocity_z(sds->fluid);
+ unsigned char *obstacle = smoke_get_obstacle(sds->fluid);
+ int bigres[3];
+
+ // mostly copied from particle code
+ for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
+ {
+ int cell[3];
+ size_t i = 0;
+ size_t index = 0;
+ int badcell = 0;
+ if(pa->alive == PARS_KILLED) continue;
+ else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
+ else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
+ else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
+ // VECCOPY(pos, pa->state.co);
+ // Mat4MulVecfl (ob->imat, pos);
+ // 1. get corresponding cell
+ get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, pa->state.co, cell, 0);
+ // check if cell is valid (in the domain boundary)
+ for(i = 0; i < 3; i++)
+ {
+ if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
+ {
+ badcell = 1;
+ break;
+ }
+ }
+ if(badcell)
+ continue;
+ // 2. set cell values (heat, density and velocity)
+ index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+ if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow
+ {
+ // heat[index] += sfs->temp * 0.1;
+ // density[index] += sfs->density * 0.1;
+ heat[index] = sfs->temp;
+ density[index] = sfs->density;
+
+ /*
+ velocity_x[index] = pa->state.vel[0];
+ velocity_y[index] = pa->state.vel[1];
+ velocity_z[index] = pa->state.vel[2];
+ */
+
+ // obstacle[index] |= 2;
+ // we need different handling for the high-res feature
+ if(bigdensity)
+ {
+ // init all surrounding cells according to amplification, too
+ int i, j, k;
+
+ smoke_turbulence_get_res(smd->domain->wt, bigres);
+
+ for(i = 0; i < smd->domain->amplify + 1; i++)
+ for(j = 0; j < smd->domain->amplify + 1; j++)
+ for(k = 0; k < smd->domain->amplify + 1; k++)
+ {
+ index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
+ bigdensity[index] = sfs->density;
+ }
+ }
+ }
+ else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow
+ {
+ heat[index] = 0.f;
+ density[index] = 0.f;
+ velocity_x[index] = 0.f;
+ velocity_y[index] = 0.f;
+ velocity_z[index] = 0.f;
+ // we need different handling for the high-res feature
+ if(bigdensity)
+ {
+ // init all surrounding cells according to amplification, too
+ int i, j, k;
+ smoke_turbulence_get_res(smd->domain->wt, bigres);
+
+ for(i = 0; i < smd->domain->amplify + 1; i++)
+ for(j = 0; j < smd->domain->amplify + 1; j++)
+ for(k = 0; k < smd->domain->amplify + 1; k++)
+ {
+ index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
+ bigdensity[index] = 0.f;
+ }
+ }
+ } // particles loop
+ }
+ }
+ else
+ {
+ /*
+ for()
+ {
+ // no psys
+ BVHTreeNearest nearest;
+ nearest.index = -1;
+ nearest.dist = FLT_MAX;
+
+ BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
+ }*/
+ }
+ }
+ }
+ if(sds->fluid_group)
+ go = go->next;
+ else
+ base= base->next;
+ }
+ }
+
+ // do effectors
+ /*
+ if(sds->eff_group)
+ {
+ for(go = sds->eff_group->gobject.first; go; go = go->next)
+ {
+ if(go->ob)
+ {
+ if(ob->pd)
+ {
+
+ }
+ }
+ }
+ }
+ */
+
+ // do collisions
+ if(1)
+ {
+ Object *otherobj = NULL;
+ ModifierData *md = NULL;
+
+ if(sds->coll_group) // we use groups since we have 2 domains
+ go = sds->coll_group->gobject.first;
+ else
+ base = scene->base.first;
+
+ while(base || go)
+ {
+ otherobj = NULL;
+ if(sds->coll_group)
+ {
+ if(go->ob)
+ otherobj = go->ob;
+ }
+ else
+ otherobj = base->object;
+ if(!otherobj)
+ {
+ if(sds->coll_group)
+ go = go->next;
+ else
+ base= base->next;
+ continue;
+ }
+ md = modifiers_findByType(otherobj, eModifierType_Smoke);
+
+ // check for active smoke modifier
+ if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+ {
+ SmokeModifierData *smd2 = (SmokeModifierData *)md;
+
+ if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
+ {
+ // we got nice collision object
+ SmokeCollSettings *scs = smd2->coll;
+ size_t i, j;
+ unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
+
+ for(i = 0; i < scs->numpoints; i++)
+ {
+ int badcell = 0;
+ size_t index = 0;
+ int cell[3];
+
+ // 1. get corresponding cell
+ get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, &scs->points[3 * i], cell, 0);
+
+ // check if cell is valid (in the domain boundary)
+ for(j = 0; j < 3; j++)
+ if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
+ {
+ badcell = 1;
+ break;
+ }
+
+ if(badcell)
+ continue;
+ // 2. set cell values (heat, density and velocity)
+ index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+
+ // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
+ // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
+ obstacles[index] = 1;
+ // for moving gobstacles
+ /*
+ const LbmFloat maxVelVal = 0.1666;
+ const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
+
+ LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec);
+ {
+ const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5;
+ USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);
+ if(usqr>maxusqr) {
+ // cutoff at maxVelVal
+ for(int jj=0; jj<3; jj++) {
+ if(objvel[jj]>0.) objvel[jj] = maxVelVal;
+ if(objvel[jj]<0.) objvel[jj] = -maxVelVal;
+ }
+ }
+ }
+ const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) );
+ const LbmVec oldov=objvel; // debug
+ objvel = vec2L((*pNormals)[n]) *dp;
+ */
+ }
+ }
+ }
+
+ if(sds->coll_group)
+ go = go->next;
+ else
+ base= base->next;
+ }
+ }
+}
void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{
if((smd->type & MOD_SMOKE_TYPE_FLOW))
{
- if(scene->r.cfra >= smd->time)
- smokeModifier_init(smd, ob, scene, dm);
+ if(scene->r.cfra >= smd->time)
+ smokeModifier_init(smd, ob, scene, dm);
if(scene->r.cfra > smd->time)
{
@@ -774,7 +1085,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(smd->coll->dm)
smd->coll->dm->release(smd->coll->dm);
- smd->coll->dm = CDDM_copy(dm, 0);
+ smd->coll->dm = CDDM_copy(dm, 1);
// rigid movement support
Mat4CpyMat4(smd->coll->mat_old, smd->coll->mat);
@@ -788,515 +1099,128 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
- PointCache *cache;
+ SmokeDomainSettings *sds = smd->domain;
+ float light[3];
+ PointCache *cache = NULL;
PTCacheID pid;
- float timescale;
- int cache_result = 0;
+ PointCache *cache_wt = NULL;
+ PTCacheID pid_wt;
int startframe, endframe, framenr;
- SmokeDomainSettings *sds = smd->domain;
- float light[3] = {0.0,0.0,0.0};
- int have_lamp = 0;
-
- // printf("smd->type & MOD_SMOKE_TYPE_DOMAIN\n");
+ float timescale;
+ int cache_result = 0, cache_result_wt = 0;
framenr = scene->r.cfra;
- cache = sds->point_cache[0];
+ // printf("time: %d\n", scene->r.cfra);
+ if(framenr == smd->time)
+ return;
+
+ cache = sds->point_cache[0];
BKE_ptcache_id_from_smoke(&pid, ob, smd);
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
- /* handle continuous simulation with the play button */
- if(BKE_ptcache_get_continue_physics())
- {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
-
- if(!smokeModifier_init(smd, ob, scene, dm))
- return;
-
- if(!smd->domain->fluid)
- return;
-
- smoke_simulate_domain(smd, scene, ob, dm);
+ cache_wt = sds->point_cache[1];
+ BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);
- {
- Base *base_tmp = NULL;
-
- for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
- {
- if(base_tmp->object->type == OB_LAMP)
- {
- Lamp *la = (Lamp *)base_tmp->object->data;
-
- if(la->type == LA_LOCAL)
- {
- VECCOPY(light, base_tmp->object->obmat[3]);
- have_lamp = 1;
- break;
- }
- }
- }
- }
-
- smoke_prepare_View(smd, (float)framenr, light, have_lamp);
-
- return;
+ if(!smd->domain->fluid)
+ {
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
}
-
+
if(framenr < startframe)
- {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ return;
- // we got back in time, reset smoke in this case (TODO: use cache later)
- // smd->time = scene->r.cfra;
- // smokeModifier_reset(smd);
+ if(framenr > endframe)
+ return;
+ if(!smd->domain->fluid && (framenr != startframe))
return;
- }
- else if(framenr > endframe)
- {
- framenr = endframe;
- }
- if(!(cache->flag & PTCACHE_SIMULATION_VALID))
- {
- // printf("reseting\n");
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
- }
-
+ // printf("startframe: %d, framenr: %d\n", startframe, framenr);
+
if(!smokeModifier_init(smd, ob, scene, dm))
+ {
+ printf("bad smokeModifier_init\n");
return;
-
- if(!smd->domain->fluid)
- return;
+ }
/* try to read from cache */
- cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
+ cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
// printf("cache_result: %d\n", cache_result);
if(cache_result == PTCACHE_READ_EXACT)
{
- SmokeDomainSettings *sds = smd->domain;
-
cache->flag |= PTCACHE_SIMULATION_VALID;
cache->simframe= framenr;
- sds->v3dnum = framenr;
- // printf("PTCACHE_READ_EXACT\n");
- return;
+ if(sds->wt)
+ {
+ cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec);
+
+ if(cache_result_wt == PTCACHE_READ_EXACT)
+ {
+ cache_wt->flag |= PTCACHE_SIMULATION_VALID;
+ cache_wt->simframe= framenr;
+ }
}
- else if(cache_result==PTCACHE_READ_OLD)
- {
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
-
- // printf("PTCACHE_READ_OLD\n");
-
- cache->flag |= PTCACHE_SIMULATION_VALID;
- }
- else if(ob->id.lib || (cache->flag & PTCACHE_BAKED))
- {
- /* if baked and nothing in cache, do nothing */
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
-
- // printf("PTCACHE_BAKED\n");
return;
}
- else if((cache_result==0) && (startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID))
- {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
- return;
- }
+ tstart();
+
+ smoke_calc_domain(scene, ob, smd);
+ // set new time
+ smd->time = scene->r.cfra;
+
/* do simulation */
// low res
cache->flag |= PTCACHE_SIMULATION_VALID;
cache->simframe= framenr;
- smoke_simulate_domain(smd, scene, ob, dm);
+ // simulate the actual smoke (c++ code in intern/smoke)
+ // DG: interesting commenting this line + deactivating loading of noise files
+ if(framenr!=startframe)
+ smoke_step(sds->fluid, smd->time);
- if(sds->wt)
- smoke_turbulence_step(sds->wt, sds->fluid);
+ // create shadows before writing cache so we get nice shadows for sstartframe, too
+ if(get_lamp(scene, light))
+ smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
+
+ BKE_ptcache_write_cache(&pid, framenr);
+ if(sds->wt)
{
- Base *base_tmp = NULL;
+ if(framenr!=startframe)
+ smoke_turbulence_step(sds->wt, sds->fluid);
- for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
- {
- if(base_tmp->object->type == OB_LAMP)
- {
- Lamp *la = (Lamp *)base_tmp->object->data;
-
- if(la->type == LA_LOCAL)
- {
- VECCOPY(light, base_tmp->object->obmat[3]);
- have_lamp = 1;
- break;
- }
- }
- }
+ cache_wt->flag |= PTCACHE_SIMULATION_VALID;
+ cache_wt->simframe= framenr;
+ BKE_ptcache_write_cache(&pid_wt, framenr);
}
- smoke_prepare_View(smd, (float)framenr, light, have_lamp);
-
- BKE_ptcache_write_cache(&pid, framenr);
-
- // printf("Writing cache_low, %d\n", framenr);
-
-
tend();
- // printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
+ printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
}
}
-void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
+static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct)
{
- GroupObject *go = NULL;
- Base *base = NULL;
- SmokeDomainSettings *sds = smd->domain;
-
- tstart();
-
- if(sds->flags & MOD_SMOKE_DISSOLVE)
- smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
-
- // do flows and fluids
- if(1)
- {
- Object *otherobj = NULL;
- ModifierData *md = NULL;
-
- if(sds->fluid_group) // we use groups since we have 2 domains
- go = sds->fluid_group->gobject.first;
- else
- base = scene->base.first;
-
- while(base || go)
- {
- otherobj = NULL;
-
- if(sds->fluid_group)
- {
- if(go->ob)
- otherobj = go->ob;
- }
- else
- otherobj = base->object;
-
- if(!otherobj)
- {
- if(sds->fluid_group)
- go = go->next;
- else
- base= base->next;
-
- continue;
- }
-
- md = modifiers_findByType(otherobj, eModifierType_Smoke);
-
- // check for active smoke modifier
- if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
- {
- SmokeModifierData *smd2 = (SmokeModifierData *)md;
-
- // check for initialized smoke object
- if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
- {
- // we got nice flow object
- SmokeFlowSettings *sfs = smd2->flow;
-
- if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
- {
- ParticleSystem *psys = sfs->psys;
- ParticleSettings *part=psys->part;
- ParticleData *pa = NULL;
- int p = 0;
- float *density = smoke_get_density(sds->fluid);
- // float *bigdensity = smoke_turbulence_get_density(sds->wt);
- float *heat = smoke_get_heat(sds->fluid);
- float *velocity_x = smoke_get_velocity_x(sds->fluid);
- float *velocity_y = smoke_get_velocity_y(sds->fluid);
- float *velocity_z = smoke_get_velocity_z(sds->fluid);
- unsigned char *obstacle = smoke_get_obstacle(sds->fluid);
-
- // debug printf("found flow psys\n");
-
- // mostly copied from particle code
- for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
- {
- int cell[3];
- size_t i = 0;
- size_t index = 0;
- int badcell = 0;
-
- if(pa->alive == PARS_KILLED) continue;
- else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
- else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
- else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
-
- // VECCOPY(pos, pa->state.co);
- // Mat4MulVecfl (ob->imat, pos);
-
- // 1. get corresponding cell
- get_cell(sds->p0, sds->res, sds->dx, pa->state.co, cell, 0);
-
- // check if cell is valid (in the domain boundary)
- for(i = 0; i < 3; i++)
- {
- if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
- {
- badcell = 1;
- break;
- }
- }
-
- if(badcell)
- continue;
-
- // 2. set cell values (heat, density and velocity)
- index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
-
- if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow
- {
- // heat[index] += sfs->temp * 0.1;
- // density[index] += sfs->density * 0.1;
-
- heat[index] = sfs->temp;
- density[index] = sfs->density;
-
- /*
- velocity_x[index] = pa->state.vel[0];
- velocity_y[index] = pa->state.vel[1];
- velocity_z[index] = pa->state.vel[2];
- */
- obstacle[index] |= 2;
- }
- else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow
- {
- heat[index] = 0.f;
- density[index] = 0.f;
- velocity_x[index] = 0.f;
- velocity_y[index] = 0.f;
- velocity_z[index] = 0.f;
- }
- }
- }
- else
- {
- /*
- for()
- {
- // no psys
- BVHTreeNearest nearest;
-
- nearest.index = -1;
- nearest.dist = FLT_MAX;
-
- BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
- }*/
- }
- }
- }
-
- if(sds->fluid_group)
- go = go->next;
- else
- base= base->next;
- }
- }
-
- // do effectors
- /*
- if(sds->eff_group)
- {
- for(go = sds->eff_group->gobject.first; go; go = go->next)
- {
- if(go->ob)
- {
- if(ob->pd)
- {
-
- }
- }
- }
- }
- */
-
- // do collisions
- if(1)
- {
- Object *otherobj = NULL;
- ModifierData *md = NULL;
-
- if(sds->coll_group) // we use groups since we have 2 domains
- go = sds->coll_group->gobject.first;
- else
- base = scene->base.first;
-
- while(base || go)
- {
- otherobj = NULL;
-
- if(sds->coll_group)
- {
- if(go->ob)
- otherobj = go->ob;
- }
- else
- otherobj = base->object;
-
- if(!otherobj)
- {
- if(sds->coll_group)
- go = go->next;
- else
- base= base->next;
-
- continue;
- }
-
- md = modifiers_findByType(otherobj, eModifierType_Smoke);
-
- // check for active smoke modifier
- if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
- {
- SmokeModifierData *smd2 = (SmokeModifierData *)md;
-
- if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
- {
- // we got nice collision object
- SmokeCollSettings *scs = smd2->coll;
- size_t i, j;
- unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
-
- for(i = 0; i < scs->numpoints; i++)
- {
- int badcell = 0;
- size_t index = 0;
- int cell[3];
-
- // 1. get corresponding cell
- get_cell(sds->p0, sds->res, sds->dx, &scs->points[3 * i], cell, 0);
-
- // check if cell is valid (in the domain boundary)
- for(j = 0; j < 3; j++)
- if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
- {
- badcell = 1;
- break;
- }
-
- if(badcell)
- continue;
-
- // 2. set cell values (heat, density and velocity)
- index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
-
- // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
- // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
-
- obstacles[index] = 1;
-
- // for moving gobstacles
- /*
- const LbmFloat maxVelVal = 0.1666;
- const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
-
- LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); {
- const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5;
- USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);
- if(usqr>maxusqr) {
- // cutoff at maxVelVal
- for(int jj=0; jj<3; jj++) {
- if(objvel[jj]>0.) objvel[jj] = maxVelVal;
- if(objvel[jj]<0.) objvel[jj] = -maxVelVal;
- }
- } }
-
- const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) );
- const LbmVec oldov=objvel; // debug
- objvel = vec2L((*pNormals)[n]) *dp;
- */
- }
- }
- }
-
- if(sds->coll_group)
- go = go->next;
- else
- base= base->next;
- }
- }
-
- // set new time
- smd->time = scene->r.cfra;
-
- // simulate the actual smoke (c++ code in intern/smoke)
- smoke_step(sds->fluid, smd->time);
- }
-
-static int calc_voxel_transp(float *input, int res[3], int *pixel, float *tRay)
- {
const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]);
// T_ray *= T_vox
- *tRay *= input[index*4];
-
- return *tRay;
- }
-
-// forward decleration
-void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb);
-
-// update necessary information for 3dview
-void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light)
-{
- float *density = NULL;
- int x, y, z;
- size_t cells, i;
- SmokeDomainSettings *sds = smd->domain;
-
- // update 3dview
- density = smoke_get_density(smd->domain->fluid);
- for(x = 0; x < smd->domain->res[0]; x++)
- for(y = 0; y < smd->domain->res[1]; y++)
- for(z = 0; z < smd->domain->res[2]; z++)
- {
- size_t index;
-
- index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
- // Transparency computation
- // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
- // T_vox = exp(-C_ext * h)
- // C_ext/sigma_t = density * C_ext
- smd->domain->view3d[index * 4] = smd->domain->view3d[index * 4 + 1] =
- smd->domain->view3d[index * 4 + 2] = exp(-density[index] * 7.0 * smd->domain->dx);
- smd->domain->view3d[index * 4 + 3] = 1.0 - smd->domain->view3d[index * 4];
-
- }
-
- if(have_light)
+ *tRay *= exp(input[index]*correct);
+
+ if(result[index] < 0.0f)
{
- smoke_calc_transparency(sds->view3d, sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp);
+#pragma omp critical
+ result[index] = *tRay;
+ }
- cells = smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2];
- for(i = 0; i < cells; i++)
-{
- smd->domain->view3d[i * 4] = smd->domain->view3d[i * 4 + 1] =
- smd->domain->view3d[i * 4 + 2] = smd->domain->view3d[i * 4 + 1] * smd->domain->view3d[i * 4 + 0];
-}
-}
- smd->domain->v3dnum = framenr;
+ return *tRay;
}
long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
@@ -1317,7 +1241,7 @@ long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
return totalMB;
}
-static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *input, int res[3])
+static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct)
{
int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
int pixel[3];
@@ -1344,8 +1268,8 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
err_1 = dy2 - l;
err_2 = dz2 - l;
for (i = 0; i < l; i++) {
- if(cb(input, res, pixel, tRay) < 0.0)
- return;
+ if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
+ break;
if (err_1 > 0) {
pixel[1] += y_inc;
err_1 -= dx2;
@@ -1362,8 +1286,8 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
err_1 = dx2 - m;
err_2 = dz2 - m;
for (i = 0; i < m; i++) {
- if(cb(input, res, pixel, tRay) < 0.0f)
- return;
+ if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
+ break;
if (err_1 > 0) {
pixel[0] += x_inc;
err_1 -= dy2;
@@ -1380,8 +1304,8 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
err_1 = dy2 - n;
err_2 = dx2 - n;
for (i = 0; i < n; i++) {
- if(cb(input, res, pixel, tRay) < 0.0f)
- return;
+ if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
+ break;
if (err_1 > 0) {
pixel[1] += y_inc;
err_1 -= dz2;
@@ -1395,7 +1319,7 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
pixel[2] += z_inc;
}
}
- cb(input, res, pixel, tRay);
+ cb(result, input, res, pixel, tRay, correct);
}
static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct)
@@ -1419,12 +1343,12 @@ static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int
}
}
-void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb)
+static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct)
{
int x, y, z;
float bv[6];
- // x
+ memset(result, -1, sizeof(float)*res[0]*res[1]*res[2]); // x
bv[0] = p0[0];
bv[1] = p1[0];
// y
@@ -1434,7 +1358,7 @@ void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], fl
bv[4] = p0[2];
bv[5] = p1[2];
-// #pragma omp parallel for schedule(static) private(y, z)
+#pragma omp parallel for schedule(static) private(y, z)
for(x = 0; x < res[0]; x++)
for(y = 0; y < res[1]; y++)
for(z = 0; z < res[2]; z++)
@@ -1447,6 +1371,8 @@ void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], fl
index = smoke_get_index(x, res[0], y, res[1], z);
+ if(result[index] >= 0.0f)
+ continue;
voxelCenter[0] = p0[0] + dx * x + dx * 0.5;
voxelCenter[1] = p0[1] + dx * y + dx * 0.5;
voxelCenter[2] = p0[2] + dx * z + dx * 0.5;
@@ -1463,10 +1389,11 @@ void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], fl
get_cell(p0, res, dx, light, cell, 1);
}
- bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, res);
+ bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, input, res, correct);
// convention -> from a RGBA float array, use G value for tRay
- result[index*4 + 1] = tRay;
+// #pragma omp critical
+ result[index] = tRay;
}
}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 094ea37afff..2e62ecb8af3 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -58,7 +58,6 @@ variables on the UI for now
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h" /* here is the softbody struct */
-#include "DNA_particle_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -77,7 +76,6 @@ variables on the UI for now
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_object.h"
-#include "BKE_particle.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
@@ -495,32 +493,21 @@ static void ccd_build_deflector_hash(Scene *scene, Object *vertexowner, GHash *h
while (base) {
/*Only proceed for mesh object in same layer */
if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
- int particles=0;
ob= base->object;
if((vertexowner) && (ob == vertexowner)) {
- if(vertexowner->soft->particles){
- particles=1;
- }
- else {
- /* if vertexowner is given we don't want to check collision with owner object */
- base = base->next;
- continue;
- }
+ /* if vertexowner is given we don't want to check collision with owner object */
+ base = base->next;
+ continue;
}
/*+++ only with deflecting set */
if(ob->pd && ob->pd->deflect && BLI_ghash_lookup(hash, ob) == 0) {
DerivedMesh *dm= NULL;
- if(particles) {
- dm = psys_get_modifier(ob,psys_get_current(ob))->dm;
- }
- else {
- if(ob->softflag & OB_SB_COLLFINAL) /* so maybe someone wants overkill to collide with subsurfed */
- dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
- else
- dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
- }
+ if(ob->softflag & OB_SB_COLLFINAL) /* so maybe someone wants overkill to collide with subsurfed */
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ else
+ dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
if(dm){
ccd_Mesh *ccdmesh = ccd_mesh_make(ob, dm);
@@ -3572,107 +3559,6 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
}
}
-
-static void springs_from_particles(Object *ob)
-{
- ParticleSystem *psys;
- ParticleSystemModifierData *psmd=0;
- ParticleData *pa=0;
- HairKey *key=0;
- SoftBody *sb;
- BodyPoint *bp;
- BodySpring *bs;
- int a,k;
- float hairmat[4][4];
-
- if(ob && ob->soft && ob->soft->particles) {
- psys= ob->soft->particles;
- sb= ob->soft;
- psmd = psys_get_modifier(ob, psys);
-
- bp= sb->bpoint;
- for(a=0, pa=psys->particles; a<psys->totpart; a++, pa++) {
- for(k=0, key=pa->hair; k<pa->totkey; k++, bp++, key++) {
- VECCOPY(bp->origS, key->co);
-
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
-
- Mat4MulVecfl(hairmat, bp->origS);
- }
- }
-
- for(a=0, bs=sb->bspring; a<sb->totspring; a++, bs++)
- bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
- }
-}
-
-static void particles_to_softbody(Scene *scene, Object *ob)
-{
- SoftBody *sb;
- BodyPoint *bp;
- BodySpring *bs;
- ParticleData *pa;
- HairKey *key;
- ParticleSystem *psys= ob->soft->particles;
- float goalfac;
- int a, k, curpoint;
- int totpoint= psys_count_keys(psys);
- int totedge= totpoint-psys->totpart;
-
- /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
- renew_softbody(scene, ob, totpoint, totedge);
-
- /* find first BodyPoint index for each particle */
- if(psys->totpart > 0) {
- psys->particles->bpi = 0;
- for(a=1, pa=psys->particles+1; a<psys->totpart; a++, pa++)
- pa->bpi = (pa-1)->bpi + (pa-1)->totkey;
- }
-
- /* we always make body points */
- sb= ob->soft;
- bp= sb->bpoint;
- bs= sb->bspring;
- goalfac= ABS(sb->maxgoal - sb->mingoal);
-
- if((ob->softflag & OB_SB_GOAL)) {
- for(a=0, pa=psys->particles; a<psys->totpart; a++, pa++) {
- for(k=0, key=pa->hair; k<pa->totkey; k++,bp++,key++) {
- if(k) {
- bp->goal= key->weight;
- bp->goal= sb->mingoal + bp->goal*goalfac;
- bp->goal= (float)pow(bp->goal, 4.0f);
- }
- else{
- /* hair roots are allways fixed fully to goal */
- bp->goal= 1.0f;
- }
- }
- }
- }
-
- bp= sb->bpoint;
- curpoint=0;
- for(a=0, pa=psys->particles; a<psys->totpart; a++, curpoint++, pa++) {
- for(k=0; k<pa->totkey-1; k++,bs++,curpoint++) {
- bs->v1=curpoint;
- bs->v2=curpoint+1;
- bs->strength= 1.0;
- bs->order=1;
- }
- }
-
- build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
- /* insert *other second order* springs if desired */
- if(sb->secondspring > 0.0000001f) {
- add_2nd_order_springs(ob,sb->secondspring*10.0); /* exploits the the first run of build_bps_springlist(ob);*/
- build_bps_springlist(ob); /* yes we need to do it again*/
- }
- springs_from_particles(ob); /* write the 'rest'-lenght of the springs */
- if(ob->softflag & OB_SB_SELF)
- calculate_collision_balls(ob);
-}
-
/* copies softbody result back in object */
static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, int local)
{
@@ -3796,44 +3682,16 @@ void sbSetInterruptCallBack(int (*f)(void))
static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts)
{
- ParticleSystemModifierData *psmd= NULL;
- ParticleData *pa= NULL;
- HairKey *key= NULL;
BodyPoint *bp;
- float hairmat[4][4];
int a;
- /* update the vertex locations */
- if(sb->particles && sb->particles->totpart>0) {
- psmd= psys_get_modifier(ob,sb->particles);
-
- pa= sb->particles->particles;
- key= pa->hair;
-
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
-
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
/* store where goals are now */
VECCOPY(bp->origS, bp->origE);
/* copy the position of the goals at desired end time */
- if(sb->particles) {
- if(key == pa->hair + pa->totkey) {
- pa++;
- key = pa->hair;
-
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
- VECCOPY(bp->origE, key->co);
- Mat4MulVecfl(hairmat,bp->origE);
-
- key++;
- }
- else{
- VECCOPY(bp->origE, vertexCos[a]);
- /* vertexCos came from local world, go global */
- Mat4MulVecfl(ob->obmat, bp->origE);
- }
+ VECCOPY(bp->origE, vertexCos[a]);
+ /* vertexCos came from local world, go global */
+ Mat4MulVecfl(ob->obmat, bp->origE);
/* just to be save give bp->origT a defined value
will be calulated in interpolate_exciter()*/
VECCOPY(bp->origT, bp->origE);
@@ -3842,37 +3700,12 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts)
{
- ParticleSystemModifierData *psmd= NULL;
- HairKey *key= NULL;
- ParticleData *pa= NULL;
BodyPoint *bp;
- float hairmat[4][4];
int a;
- if(sb->particles && sb->particles->totpart>0) {
- psmd= psys_get_modifier(ob, sb->particles);
- pa= sb->particles->particles;
- key= pa->hair;
-
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
-
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
- if(sb->particles) {
- if(key == pa->hair + pa->totkey) {
- pa++;
- key = pa->hair;
-
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
- VECCOPY(bp->pos, key->co);
- Mat4MulVecfl(hairmat, bp->pos);
- key++;
- }
- else {
- VECCOPY(bp->pos, vertexCos[a]);
- Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/
- }
+ VECCOPY(bp->pos, vertexCos[a]);
+ Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/
VECCOPY(bp->origS, bp->pos);
VECCOPY(bp->origE, bp->pos);
VECCOPY(bp->origT, bp->pos);
@@ -3901,20 +3734,18 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
sb_new_scratch(sb); /* make a new */
sb->scratch->needstobuildcollider=1;
- if((sb->particles)==0) {
- /* copy some info to scratch */
- switch(ob->type) {
- case OB_MESH:
- if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob);
- break;
- case OB_LATTICE:
- break;
- case OB_CURVE:
- case OB_SURF:
- break;
- default:
- break;
- }
+ /* copy some info to scratch */
+ switch(ob->type) {
+ case OB_MESH:
+ if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob);
+ break;
+ case OB_LATTICE:
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ break;
+ default:
+ break;
}
}
@@ -4050,8 +3881,6 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
/* simulates one step. framenr is in frames */
void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
{
- ParticleSystemModifierData *psmd=0;
- ParticleData *pa=0;
SoftBody *sb= ob->soft;
PointCache *cache;
PTCacheID pid;
@@ -4080,7 +3909,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
if(framenr < startframe) {
cache->flag &= ~PTCACHE_SIMULATION_VALID;
cache->simframe= 0;
- cache->last_exact= 0;
+ //cache->last_exact= 0;
return;
}
@@ -4092,25 +3921,20 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
if(sb->bpoint == NULL ||
((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) {
- if(sb->particles){
- particles_to_softbody(scene, ob);
- }
- else {
- switch(ob->type) {
- case OB_MESH:
- mesh_to_softbody(scene, ob);
- break;
- case OB_LATTICE:
- lattice_to_softbody(scene, ob);
- break;
- case OB_CURVE:
- case OB_SURF:
- curve_surf_to_softbody(scene, ob);
- break;
- default:
- renew_softbody(scene, ob, numVerts, 0);
- break;
- }
+ switch(ob->type) {
+ case OB_MESH:
+ mesh_to_softbody(scene, ob);
+ break;
+ case OB_LATTICE:
+ lattice_to_softbody(scene, ob);
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ curve_surf_to_softbody(scene, ob);
+ break;
+ default:
+ renew_softbody(scene, ob, numVerts, 0);
+ break;
}
softbody_update_positions(ob, sb, vertexCos, numVerts);
@@ -4128,8 +3952,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
softbody_update_positions(ob, sb, vertexCos, numVerts);
softbody_step(scene, ob, sb, dtime);
- if(sb->particles==0)
- softbody_to_object(ob, vertexCos, numVerts, 0);
+ softbody_to_object(ob, vertexCos, numVerts, 0);
return;
}
@@ -4137,25 +3960,33 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
/* still no points? go away */
if(sb->totpoint==0) return;
- if(sb->particles){
- psmd= psys_get_modifier(ob, sb->particles);
- pa= sb->particles->particles;
+ if(framenr == startframe) {
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+
+ /* first frame, no simulation to do, just set the positions */
+ softbody_update_positions(ob, sb, vertexCos, numVerts);
+
+ cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+ return;
}
/* try to read from cache */
cache_result = BKE_ptcache_read_cache(&pid, framenr, scene->r.frs_sec);
if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ softbody_to_object(ob, vertexCos, numVerts, sb->local);
+
cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
- if(sb->particles==0)
- softbody_to_object(ob, vertexCos, numVerts, sb->local);
+ if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+ BKE_ptcache_write_cache(&pid, framenr);
return;
}
else if(cache_result==PTCACHE_READ_OLD) {
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
cache->flag |= PTCACHE_SIMULATION_VALID;
}
else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
@@ -4166,41 +3997,23 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
return;
}
- if(framenr == startframe) {
- if(cache->flag & PTCACHE_REDO_NEEDED) {
- softbody_update_positions(ob, sb, vertexCos, numVerts);
- softbody_reset(ob, sb, vertexCos, numVerts);
- cache->flag &= ~PTCACHE_REDO_NEEDED;
- }
- /* first frame, no simulation to do, just set the positions */
- softbody_update_positions(ob, sb, vertexCos, numVerts);
+ /* if on second frame, write cache for first frame */
+ if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
+ BKE_ptcache_write_cache(&pid, startframe);
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
+ softbody_update_positions(ob, sb, vertexCos, numVerts);
- /* don't write cache on first frame, but on second frame write
- * cache for frame 1 and 2 */
- }
- else {
- /* if on second frame, write cache for first frame */
- if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
- BKE_ptcache_write_cache(&pid, startframe);
+ /* checking time: */
+ dtime = framedelta*timescale;
- softbody_update_positions(ob, sb, vertexCos, numVerts);
+ softbody_step(scene, ob, sb, dtime);
- /* do simulation */
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
-
- /* checking time: */
- dtime = framedelta*timescale;
+ softbody_to_object(ob, vertexCos, numVerts, 0);
- softbody_step(scene, ob, sb, dtime);
-
- if(sb->particles==0)
- softbody_to_object(ob, vertexCos, numVerts, 0);
+ /* do simulation */
+ cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
- BKE_ptcache_write_cache(&pid, framenr);
- }
+ BKE_ptcache_write_cache(&pid, framenr);
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index c6f9db6fda9..2d5d8dad7a8 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -34,7 +34,7 @@
void sound_init()
{
AUD_Specs specs;
- int device, buffersize, success;
+ int device, buffersize;
device = U.audiodevice;
buffersize = U.mixbufsize;
@@ -54,15 +54,8 @@ void sound_init()
if(specs.channels <= AUD_CHANNELS_INVALID)
specs.channels = AUD_CHANNELS_STEREO;
- if(!AUD_init(device, specs, buffersize)) {
- if(device == AUD_SDL_DEVICE)
- success= AUD_init(AUD_OPENAL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE*4);
- else
- success= AUD_init(AUD_SDL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE*4);
-
- if(!success)
- AUD_init(AUD_NULL_DEVICE, specs, buffersize);
- }
+ if(!AUD_init(device, specs, buffersize))
+ AUD_init(AUD_NULL_DEVICE, specs, buffersize);
}
void sound_exit()
@@ -86,11 +79,11 @@ struct bSound* sound_new_file(struct Main *main, char* filename)
sound = alloc_libblock(&main->sound, ID_SO, filename+len);
strcpy(sound->name, filename);
- sound->type = SOUND_TYPE_FILE;
+// XXX unused currently sound->type = SOUND_TYPE_FILE;
sound_load(main, sound);
- if(!sound->snd_sound)
+ if(!sound->handle)
{
free_libblock(&main->sound, sound);
sound = NULL;
@@ -116,7 +109,7 @@ struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source)
sound_load(CTX_data_main(C), sound);
- if(!sound->snd_sound)
+ if(!sound->handle)
{
free_libblock(&CTX_data_main(C)->sound, sound);
sound = NULL;
@@ -142,7 +135,7 @@ struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, floa
sound_load(CTX_data_main(C), sound);
- if(!sound->snd_sound)
+ if(!sound->handle)
{
free_libblock(&CTX_data_main(C)->sound, sound);
sound = NULL;
@@ -169,22 +162,35 @@ void sound_cache(struct bSound* sound, int ignore)
if(sound->cache && !ignore)
AUD_unload(sound->cache);
- sound->cache = AUD_bufferSound(sound->snd_sound);
+ sound->cache = AUD_bufferSound(sound->handle);
+ sound->changed++;
+}
+
+void sound_delete_cache(struct bSound* sound)
+{
+ if(sound->cache)
+ {
+ AUD_unload(sound->cache);
+ sound->cache = NULL;
+ }
}
void sound_load(struct Main *main, struct bSound* sound)
{
if(sound)
{
- if(sound->snd_sound)
+ if(sound->handle)
{
- AUD_unload(sound->snd_sound);
- sound->snd_sound = NULL;
+ AUD_unload(sound->handle);
+ sound->handle = NULL;
}
+// XXX unused currently
+#if 0
switch(sound->type)
{
case SOUND_TYPE_FILE:
+#endif
{
char fullpath[FILE_MAX];
char *path;
@@ -198,32 +204,32 @@ void sound_load(struct Main *main, struct bSound* sound)
if(sound->id.lib)
path = sound->id.lib->filename;
else
- path = main ? main->name : NULL;
+ path = main ? main->name : G.sce;
BLI_convertstringcode(fullpath, path);
/* but we need a packed file then */
if (pf)
- sound->snd_sound = AUD_loadBuffer((unsigned char*) pf->data, pf->size);
+ sound->handle = AUD_loadBuffer((unsigned char*) pf->data, pf->size);
/* or else load it from disk */
else
- sound->snd_sound = AUD_load(fullpath);
+ sound->handle = AUD_load(fullpath);
+ } // XXX
+// XXX unused currently
+#if 0
break;
}
case SOUND_TYPE_BUFFER:
- if(sound->child_sound && sound->child_sound->snd_sound)
- sound->snd_sound = AUD_bufferSound(sound->child_sound->snd_sound);
+ if(sound->child_sound && sound->child_sound->handle)
+ sound->handle = AUD_bufferSound(sound->child_sound->handle);
break;
case SOUND_TYPE_LIMITER:
- if(sound->child_sound && sound->child_sound->snd_sound)
- sound->snd_sound = AUD_limitSound(sound->child_sound, sound->start, sound->end);
+ if(sound->child_sound && sound->child_sound->handle)
+ sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
break;
}
-
- if(sound->cache)
- {
-
- }
+#endif
+ sound->changed++;
}
}
@@ -235,33 +241,36 @@ void sound_free(struct bSound* sound)
sound->packedfile = NULL;
}
- if(sound->snd_sound)
+ if(sound->handle)
{
- AUD_unload(sound->snd_sound);
- sound->snd_sound = NULL;
+ AUD_unload(sound->handle);
+ sound->handle = NULL;
}
}
void sound_unlink(struct bContext *C, struct bSound* sound)
{
- bSound *snd;
Scene *scene;
SoundHandle *handle;
+// XXX unused currently
+#if 0
+ bSound *snd;
for(snd = CTX_data_main(C)->sound.first; snd; snd = snd->id.next)
{
if(snd->child_sound == sound)
{
snd->child_sound = NULL;
- if(snd->snd_sound)
+ if(snd->handle)
{
- AUD_unload(sound->snd_sound);
- snd->snd_sound = NULL;
+ AUD_unload(sound->handle);
+ snd->handle = NULL;
}
sound_unlink(C, snd);
}
}
+#endif
for(scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next)
{
@@ -367,7 +376,7 @@ void sound_update_playing(struct bContext *C)
float diff = AUD_getPosition(handle->handle) * fps - cfra + handle->startframe;
if(diff < 0.0)
diff = -diff;
- if(diff > 1.0f)
+ if(diff > FPS/2.0)
{
action = 2;
}
@@ -379,9 +388,9 @@ void sound_update_playing(struct bContext *C)
{
if(handle->state == AUD_STATUS_INVALID)
{
- if(handle->source && handle->source->snd_sound)
+ if(handle->source && handle->source->handle)
{
- AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, handle->frameskip / fps, (handle->frameskip + handle->endframe - handle->startframe)/fps);
+ AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, handle->frameskip / fps, (handle->frameskip + handle->endframe - handle->startframe)/fps);
handle->handle = AUD_play(limiter, 1);
AUD_unload(limiter);
if(handle->handle)
@@ -420,10 +429,10 @@ void sound_scrub(struct bContext *C)
{
if(cfra >= handle->startframe && cfra < handle->endframe && !handle->mute)
{
- if(handle->source && handle->source->snd_sound)
+ if(handle->source && handle->source->handle)
{
int frameskip = handle->frameskip + cfra - handle->startframe;
- AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, frameskip / fps, (frameskip + 1)/fps);
+ AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, frameskip / fps, (frameskip + 1)/fps);
AUD_play(limiter, 0);
AUD_unload(limiter);
}
@@ -446,7 +455,7 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e
for(handle = scene->sound_handles.first; handle; handle = handle->next)
{
- if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->snd_sound)
+ if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->handle)
{
frameskip = handle->frameskip;
s = handle->startframe - start;
@@ -458,7 +467,7 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e
s = 0;
}
- limiter = AUD_limitSound(handle->source->snd_sound, frameskip / fps, e / fps);
+ limiter = AUD_limitSound(handle->source->handle, frameskip / fps, e / fps);
delayer = AUD_delaySound(limiter, s / fps);
AUD_playDevice(mixdown, delayer);
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 8e3d59bbc58..350b0acba9d 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -37,14 +37,22 @@
#include "BLI_blenlib.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_controller_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "DNA_text_types.h"
-#include "BKE_utildefines.h"
-#include "BKE_text.h"
-#include "BKE_library.h"
+#include "BKE_depsgraph.h"
#include "BKE_global.h"
+#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_text.h"
+#include "BKE_utildefines.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@@ -122,8 +130,10 @@ undo position
static void txt_pop_first(Text *text);
static void txt_pop_last(Text *text);
static void txt_undo_add_op(Text *text, int op);
-static void txt_undo_add_block(Text *text, int op, char *buf);
+static void txt_undo_add_block(Text *text, int op, const char *buf);
static void txt_delete_line(Text *text, TextLine *line);
+static void txt_delete_sel (Text *text);
+static void txt_make_dirty (Text *text);
/***/
@@ -451,6 +461,109 @@ Text *copy_text(Text *ta)
return tan;
}
+void unlink_text(Main *bmain, Text *text)
+{
+ bScreen *scr;
+ ScrArea *area;
+ SpaceLink *sl;
+ Scene *scene;
+ Object *ob;
+ bController *cont;
+ bConstraint *con;
+ short update;
+
+ /* dome */
+ for(scene=bmain->scene.first; scene; scene=scene->id.next)
+ if(scene->r.dometext == text)
+ scene->r.dometext = NULL;
+
+ for(ob=bmain->object.first; ob; ob=ob->id.next) {
+ /* game controllers */
+ for(cont=ob->controllers.first; cont; cont=cont->next) {
+ if(cont->type==CONT_PYTHON) {
+ bPythonCont *pc;
+
+ pc= cont->data;
+ if(pc->text==text) pc->text= NULL;
+ }
+ }
+
+ /* pyconstraints */
+ update = 0;
+
+ if(ob->type==OB_ARMATURE && ob->pose) {
+ bPoseChannel *pchan;
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for(con = pchan->constraints.first; con; con=con->next) {
+ if(con->type==CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = con->data;
+ if (data->text==text) data->text = NULL;
+ update = 1;
+
+ }
+ }
+ }
+ }
+
+ for(con = ob->constraints.first; con; con=con->next) {
+ if(con->type==CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = con->data;
+ if (data->text==text) data->text = NULL;
+ update = 1;
+ }
+ }
+
+ if(update)
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ }
+
+ /* pynodes */
+ // XXX nodeDynamicUnlinkText(&text->id);
+
+ /* text space */
+ for(scr= bmain->screen.first; scr; scr= scr->id.next) {
+ for(area= scr->areabase.first; area; area= area->next) {
+ for(sl= area->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_TEXT) {
+ SpaceText *st= (SpaceText*) sl;
+
+ if(st->text==text) {
+ st->text= NULL;
+ st->top= 0;
+ }
+ }
+ }
+ }
+ }
+
+ text->id.us= 0;
+}
+
+void clear_text(Text *text) /* called directly from rna */
+{
+ int oldstate;
+
+ oldstate = txt_get_undostate( );
+ txt_set_undostate( 1 );
+ txt_sel_all( text );
+ txt_delete_sel(text);
+ txt_set_undostate( oldstate );
+
+ txt_make_dirty(text);
+}
+
+void write_text(Text *text, char *str) /* called directly from rna */
+{
+ int oldstate;
+
+ oldstate = txt_get_undostate( );
+ txt_insert_buf( text, str );
+ txt_move_eof( text, 0 );
+ txt_set_undostate( oldstate );
+
+ txt_make_dirty(text);
+}
+
/*****************************/
/* Editing utility functions */
/*****************************/
@@ -1228,7 +1341,7 @@ char *txt_sel_to_buf (Text *text)
return buf;
}
-void txt_insert_buf(Text *text, char *in_buffer)
+void txt_insert_buf(Text *text, const char *in_buffer)
{
int i=0, l=0, j, u, len;
TextLine *add;
@@ -1457,7 +1570,7 @@ static void txt_undo_add_op(Text *text, int op)
text->undo_buf[text->undo_pos+1]= 0;
}
-static void txt_undo_add_block(Text *text, int op, char *buf)
+static void txt_undo_add_block(Text *text, int op, const char *buf)
{
int length;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 61f62b2222d..d7616ec8a9a 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -38,7 +38,7 @@
#include "PIL_dynlib.h"
-#include "MTC_matrixops.h"
+
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -368,9 +368,9 @@ int do_colorband(ColorBand *coba, float in, float out[4])
CLAMP(fac, 0.0f, 1.0f);
if(coba->ipotype==3)
- set_four_ipo(fac, t, KEY_CARDINAL);
+ key_curve_position_weights(fac, t, KEY_CARDINAL);
else
- set_four_ipo(fac, t, KEY_BSPLINE);
+ key_curve_position_weights(fac, t, KEY_BSPLINE);
out[0]= t[3]*cbd3->r +t[2]*cbd2->r +t[1]*cbd1->r +t[0]*cbd0->r;
out[1]= t[3]*cbd3->g +t[2]*cbd2->g +t[1]*cbd1->g +t[0]*cbd0->g;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index e7164dc4794..9e86dcbe491 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -613,7 +613,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
}
/* essential functions -- start, append, end */
-void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
+static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty)
{
/* Handle to the output file */
AVFormatContext* of;