diff options
Diffstat (limited to 'source/blender/blenkernel/intern/object.c')
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 432 |
1 files changed, 276 insertions, 156 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 4cb6f64569f..d9b2ce84fa5 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -60,6 +60,7 @@ #include "DNA_object_force.h" #include "DNA_object_fluidsim.h" #include "DNA_oops_types.h" +#include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" @@ -70,6 +71,7 @@ #include "BKE_armature.h" #include "BKE_action.h" +#include "BKE_colortools.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" #include "BKE_nla.h" @@ -100,6 +102,7 @@ #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_particle.h" #include "BKE_property.h" #include "BKE_sca.h" #include "BKE_scene.h" @@ -163,6 +166,15 @@ void object_free_modifiers(Object *ob) modifier_free(md); } + + /* particle modifiers were freed, so free the particlesystems as well */ + while(ob->particlesystem.first){ + ParticleSystem *psys = ob->particlesystem.first; + + BLI_remlink(&ob->particlesystem,psys); + + psys_free(ob,psys); + } } /* here we will collect all local displist stuff */ @@ -221,7 +233,6 @@ void free_object(Object *ob) MEM_freeN(ob->pose); } free_effects(&ob->effect); - BLI_freelistN(&ob->network); free_properties(&ob->prop); object_free_modifiers(ob); @@ -235,7 +246,11 @@ void free_object(Object *ob) BPY_free_scriptlink(&ob->scriptlink); - if(ob->pd) MEM_freeN(ob->pd); + if(ob->pd){ + if(ob->pd->tex) + ob->pd->tex->id.us--; + MEM_freeN(ob->pd); + } if(ob->soft) sbFree(ob->soft); if(ob->fluidsimSettings) fluidsimSettingsFree(ob->fluidsimSettings); } @@ -260,10 +275,10 @@ void unlink_object(Object *ob) Tex *tex; Ipo *ipo; Group *group; + Camera *camera; bConstraint *con; bActionStrip *strip; int a; - char *str; unlink_controllers(&ob->controllers); unlink_actuators(&ob->actuators); @@ -312,9 +327,23 @@ void unlink_object(Object *ob) bPoseChannel *pchan; for(pchan= obt->pose->chanbase.first; pchan; pchan= pchan->next) { for (con = pchan->constraints.first; con; con=con->next) { - if(ob==get_constraint_target(con, &str)) { - set_constraint_target(con, NULL, NULL); - obt->recalc |= OB_RECALC_DATA; + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + ListBase targets = {NULL, NULL}; + bConstraintTarget *ct; + + if (cti && cti->get_constraint_targets) { + cti->get_constraint_targets(con, &targets); + + for (ct= targets.first; ct; ct= ct->next) { + if (ct->tar == ob) { + ct->tar = NULL; + strcpy(ct->subtarget, ""); + obt->recalc |= OB_RECALC_DATA; + } + } + + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(con, &targets, 0); } } if(pchan->custom==ob) @@ -325,9 +354,23 @@ void unlink_object(Object *ob) sca_remove_ob_poin(obt, ob); for (con = obt->constraints.first; con; con=con->next) { - if(ob==get_constraint_target(con, &str)) { - set_constraint_target(con, NULL, NULL); - obt->recalc |= OB_RECALC_OB; + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + ListBase targets = {NULL, NULL}; + bConstraintTarget *ct; + + if (cti && cti->get_constraint_targets) { + cti->get_constraint_targets(con, &targets); + + for (ct= targets.first; ct; ct= ct->next) { + if (ct->tar == ob) { + ct->tar = NULL; + strcpy(ct->subtarget, ""); + obt->recalc |= OB_RECALC_DATA; + } + } + + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(con, &targets, 0); } } @@ -352,6 +395,47 @@ void unlink_object(Object *ob) } } + /* particle systems */ + if(obt->particlesystem.first) { + ParticleSystem *tpsys= obt->particlesystem.first; + for(; tpsys; tpsys=tpsys->next) { + if(tpsys->keyed_ob==ob) { + ParticleSystem *psys= BLI_findlink(&ob->particlesystem,tpsys->keyed_psys-1); + + if(psys && psys->keyed_ob) { + tpsys->keyed_ob= psys->keyed_ob; + tpsys->keyed_psys= psys->keyed_psys; + } + else + tpsys->keyed_ob= NULL; + + obt->recalc |= OB_RECALC_DATA; + } + + if(tpsys->target_ob==ob) { + tpsys->target_ob= NULL; + obt->recalc |= OB_RECALC_DATA; + } + + if(tpsys->part->dup_ob==ob) + tpsys->part->dup_ob= NULL; + + if(tpsys->part->flag&PART_STICKY) { + ParticleData *pa; + 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; + } + } + } + } + if(ob->pd) + obt->recalc |= OB_RECALC_DATA; + } + obt= obt->id.next; } @@ -473,6 +557,15 @@ void unlink_object(Object *ob) rem_from_group(group, ob); group= group->id.next; } + + /* cameras */ + camera= G.main->camera.first; + while(camera) { + if (camera->dof_ob==ob) { + camera->dof_ob = NULL; + } + camera= camera->id.next; + } } int exist_object(Object *obtest) @@ -573,7 +666,23 @@ void make_local_camera(Camera *cam) } } - +/* get the camera's dof value, takes the dof object into account */ +float dof_camera(Object *ob) +{ + Camera *cam = (Camera *)ob->data; + if (ob->type != OB_CAMERA) + return 0.0; + if (cam->dof_ob) { + /* too simple, better to return the distance on the view axis only + * return VecLenf(ob->obmat[3], cam->dof_ob->obmat[3]); */ + + float mat[4][4]; + Mat4Invert(ob->imat, ob->obmat); + Mat4MulMat4(mat, cam->dof_ob->obmat, ob->imat); + return fabs(mat[3][2]); + } + return cam->YF_dofdist; +} void *add_lamp(char *name) { @@ -599,7 +708,12 @@ void *add_lamp(char *name) la->area_size=la->area_sizey=la->area_sizez= 1.0; la->buffers= 1; la->buftype= LA_SHADBUF_HALFWAY; - + la->ray_samp_method = LA_SAMP_HALTON; + la->adapt_thresh = 0.001; + la->preview=NULL; + la->falloff_type = LA_FALLOFF_INVLINEAR; + la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); + curvemapping_initialize(la->curfalloff); return la; } @@ -618,8 +732,12 @@ Lamp *copy_lamp(Lamp *la) } } + lan->curfalloff = curvemapping_copy(la->curfalloff); + id_us_plus((ID *)lan->ipo); + if (la->preview) lan->preview = BKE_previewimg_copy(la->preview); + BPY_copy_scriptlink(&la->scriptlink); return lan; @@ -690,7 +808,7 @@ void free_lamp(Lamp *la) /* scriptlinks */ BPY_free_scriptlink(&la->scriptlink); - + for(a=0; a<MAX_MTEX; a++) { mtex= la->mtex[a]; if(mtex && mtex->tex) mtex->tex->id.us--; @@ -698,6 +816,9 @@ void free_lamp(Lamp *la) } la->ipo= 0; + curvemapping_free(la->curfalloff); + + BKE_previewimg_free(&la->preview); BKE_icon_delete(&la->id); la->id.icon_id = 0; } @@ -772,6 +893,7 @@ Object *add_only_object(int type, char *name) ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; ob->size[0]= ob->size[1]= ob->size[2]= 1.0; + Mat4One(ob->constinv); Mat4One(ob->parentinv); Mat4One(ob->obmat); ob->dt= OB_SHADED; @@ -850,13 +972,15 @@ void base_init_from_view3d(Base *base, View3D *v3d) VECCOPY(ob->loc, G.scene->cursor); } - v3d->viewquat[0]= -v3d->viewquat[0]; - if (ob->transflag & OB_QUAT) { - QUATCOPY(ob->quat, v3d->viewquat); - } else { - QuatToEul(v3d->viewquat, ob->rot); + if (U.flag & USER_ADD_VIEWALIGNED) { + v3d->viewquat[0]= -v3d->viewquat[0]; + if (ob->transflag & OB_QUAT) { + QUATCOPY(ob->quat, v3d->viewquat); + } else { + QuatToEul(v3d->viewquat, ob->rot); + } + v3d->viewquat[0]= -v3d->viewquat[0]; } - v3d->viewquat[0]= -v3d->viewquat[0]; } SoftBody *copy_softbody(SoftBody *sb) @@ -878,6 +1002,22 @@ SoftBody *copy_softbody(SoftBody *sb) return sbn; } +ParticleSystem *copy_particlesystem(ParticleSystem *psys) +{ + ParticleSystem *psysn; + + psysn= MEM_dupallocN(psys); + psysn->particles= MEM_dupallocN(psys->particles); + + psysn->child= MEM_dupallocN(psys->child); + + psysn->effectors.first= psysn->effectors.last= 0; + + id_us_plus((ID *)psysn->part); + + return psysn; +} + static void copy_object_pose(Object *obn, Object *ob) { bPoseChannel *chan; @@ -886,11 +1026,25 @@ static void copy_object_pose(Object *obn, Object *ob) for (chan = obn->pose->chanbase.first; chan; chan=chan->next){ bConstraint *con; - char *str; + chan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE); - for(con= chan->constraints.first; con; con= con->next) { - if(ob==get_constraint_target(con, &str)) - set_constraint_target(con, obn, NULL); + + for (con= chan->constraints.first; con; con= con->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + ListBase targets = {NULL, NULL}; + bConstraintTarget *ct; + + if (cti && cti->get_constraint_targets) { + cti->get_constraint_targets(con, &targets); + + for (ct= targets.first; ct; ct= ct->next) { + if (ct->tar == ob) + ct->tar = obn; + } + + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(con, &targets, 0); + } } } } @@ -899,6 +1053,7 @@ Object *copy_object(Object *ob) { Object *obn; ModifierData *md; + ParticleSystem *psys; int a; obn= copy_libblock(ob); @@ -920,8 +1075,6 @@ Object *copy_object(Object *ob) BLI_addtail(&obn->modifiers, nmd); } - obn->network.first= obn->network.last= 0; - BPY_copy_scriptlink(&ob->scriptlink); copy_properties(&obn->prop, &ob->prop); @@ -951,7 +1104,11 @@ Object *copy_object(Object *ob) obn->disp.first= obn->disp.last= NULL; - if(ob->pd) obn->pd= MEM_dupallocN(ob->pd); + if(ob->pd){ + obn->pd= MEM_dupallocN(ob->pd); + if(obn->pd->tex) + id_us_plus(&(obn->pd->tex->id)); + } obn->soft= copy_softbody(ob->soft); /* NT copy fluid sim setting memory */ @@ -962,6 +1119,23 @@ Object *copy_object(Object *ob) obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; } } + + obn->particlesystem.first= obn->particlesystem.last= NULL; + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + ParticleSystemModifierData *psmd; + ParticleSystem *npsys= copy_particlesystem(psys); + + BLI_addtail(&obn->particlesystem, npsys); + + /* need to update particle modifiers too */ + for(md=obn->modifiers.first; md; md=md->next) { + if(md->type==eModifierType_ParticleSystem) { + psmd= (ParticleSystemModifierData*)md; + if(psmd->psys==psys) + psmd->psys= npsys; + } + } + } obn->derivedDeform = NULL; obn->derivedFinal = NULL; @@ -1061,6 +1235,20 @@ void make_local_object(Object *ob) /* *************** PROXY **************** */ +/* when you make proxy, ensure the exposed layers are extern */ +void armature_set_id_extern(Object *ob) +{ + bArmature *arm= ob->data; + bPoseChannel *pchan; + int lay= arm->layer_protected; + + for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { + if(!(pchan->bone->layer & lay)) + id_lib_extern((ID *)pchan->custom); + } + +} + /* proxy rule: lib_object->proxy_from == the one we borrow from, set temporally while object_update */ /* local_object->proxy == pointer to library object, saved in files and read */ /* local_object->proxy_group == pointer to group dupli-object, saved in files and read */ @@ -1084,6 +1272,8 @@ void object_make_proxy(Object *ob, Object *target, Object *gob) VECCOPY(ob->loc, gob->loc); VECCOPY(ob->rot, gob->rot); VECCOPY(ob->size, gob->size); + + group_tag_recalc(gob->dup_group); } else { VECCOPY(ob->loc, target->loc); @@ -1106,6 +1296,8 @@ void object_make_proxy(Object *ob, Object *target, Object *gob) copy_object_pose(ob, target); /* data copy, object pointers in constraints */ rest_pose(ob->pose); /* clear all transforms in channels */ armature_rebuild_pose(ob, ob->data); /* set all internal links */ + + armature_set_id_extern(ob); } } @@ -1134,20 +1326,23 @@ void disable_speed_curve(int val) } /* ob can be NULL */ -float bsystem_time(Object *ob, Object *par, float cfra, float ofs) +float bsystem_time(Object *ob, float cfra, float ofs) { /* returns float ( see frame_to_float in ipo.c) */ - + + /* bluroffs and fieldoffs are ugly globals that are set by render */ cfra+= bluroffs+fieldoffs; /* global time */ cfra*= G.scene->r.framelen; - if(no_speed_curve==0) if(ob && ob->ipo) cfra= calc_ipo_time(ob->ipo, cfra); - - /* ofset frames */ - if(ob && (ob->ipoflag & OB_OFFS_PARENT)) { - if((ob->partype & PARSLOW)==0) cfra-= ob->sf; + if (ob) { + if (no_speed_curve==0 && ob->ipo) + cfra= calc_ipo_time(ob->ipo, cfra); + + /* ofset frames */ + if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0) + cfra-= ob->sf; } cfra-= ofs; @@ -1238,7 +1433,7 @@ static void ob_parcurve(Object *ob, Object *par, float mat[][4]) } /* catch exceptions: curve paths used as a duplicator */ else if(enable_cu_speed) { - ctime= bsystem_time(ob, par, (float)G.scene->r.cfra, 0.0); + ctime= bsystem_time(ob, (float)G.scene->r.cfra, 0.0); if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) { ctime /= cu->pathlen; @@ -1490,7 +1685,7 @@ void where_is_object_time(Object *ob, float ctime) if(ob==NULL) return; /* this is needed to be able to grab objects with ipos, otherwise it always freezes them */ - stime= bsystem_time(ob, 0, ctime, 0.0); + stime= bsystem_time(ob, ctime, 0.0); if(stime != ob->ctime) { ob->ctime= stime; @@ -1502,12 +1697,14 @@ void where_is_object_time(Object *ob, float ctime) else do_all_object_actions(ob); - /* do constraint ipos ..., note it needs stime */ - do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime); + /* do constraint ipos ..., note it needs stime (0 = all ipos) */ + do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 0); } else { /* but, the drivers have to be done */ if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo, stime); + /* do constraint ipos ..., note it needs stime (1 = only drivers ipos) */ + do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 1); } if(ob->parent) { @@ -1560,9 +1757,18 @@ void where_is_object_time(Object *ob, float ctime) } - /* constraints need ctime, not stime. it calls where_is_object_time and bsystem_time */ - solve_constraints (ob, TARGET_OBJECT, NULL, ctime); - + /* solve constraints */ + if (ob->constraints.first) { + bConstraintOb *cob; + + cob= constraints_make_evalob(ob, NULL, CONSTRAINT_OBTYPE_OBJECT); + + /* constraints need ctime, not stime. Some call where_is_object_time and bsystem_time */ + solve_constraints (&ob->constraints, cob, ctime); + + constraints_clear_evalob(cob); + } + if(ob->scriptlink.totscript && !during_script()) { if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript((ID *)ob, SCRIPT_REDRAW); } @@ -1728,132 +1934,26 @@ for a lamp that is the child of another object */ if(ob->track) solve_tracking(ob, ob->track->obmat); - solve_constraints(ob, TARGET_OBJECT, NULL, G.scene->r.cfra); + /* solve constraints */ + if (ob->constraints.first) { + bConstraintOb *cob; + + cob= constraints_make_evalob(ob, NULL, CONSTRAINT_OBTYPE_OBJECT); + solve_constraints (&ob->constraints, cob, G.scene->r.cfra); + constraints_clear_evalob(cob); + } /* WATCH IT!!! */ ob->ipo= ipo; - -} -extern void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight); - -void solve_constraints (Object *ob, short obtype, void *obdata, float ctime) -{ - bConstraint *con; - float tmat[4][4], focusmat[4][4], lastmat[4][4]; - int i, clear=1, tot=0; - float a=0; - float aquat[4], quat[4]; - float aloc[3], loc[3]; - float asize[3], size[3]; - float oldmat[4][4]; - float smat[3][3], rmat[3][3], mat[3][3]; - float enf; - - for (con = ob->constraints.first; con; con=con->next) { - // inverse kinematics is solved seperate - if (con->type==CONSTRAINT_TYPE_KINEMATIC) continue; - // and this we can skip completely - if (con->flag & CONSTRAINT_DISABLE) continue; - // local constraints are handled in armature.c only - if (con->flag & CONSTRAINT_LOCAL) continue; - - /* Clear accumulators if necessary*/ - if (clear) { - clear= 0; - a= 0; - tot= 0; - memset(aquat, 0, sizeof(float)*4); - memset(aloc, 0, sizeof(float)*3); - memset(asize, 0, sizeof(float)*3); - } - - enf = con->enforce; // value from ipos (from action channels) - - /* Get the targetmat */ - get_constraint_target_matrix(con, obtype, obdata, tmat, size, ctime); - - Mat4CpyMat4(focusmat, tmat); - - /* Extract the components & accumulate */ - Mat4ToQuat(focusmat, quat); - VECCOPY(loc, focusmat[3]); - Mat3CpyMat4(mat, focusmat); - Mat3ToSize(mat, size); - - a+= enf; - tot++; - - for(i=0; i<3; i++) { - aquat[i+1]+=(quat[i+1]) * enf; - aloc[i]+=(loc[i]) * enf; - asize[i]+=(size[i]-1.0f) * enf; - } - aquat[0]+=(quat[0])*enf; - Mat4CpyMat4(lastmat, focusmat); - - /* removed for now, probably becomes option? (ton) */ - - /* If the next constraint is not the same type (or there isn't one), - * then evaluate the accumulator & request a clear */ - if (TRUE) { //(!con->next)||(con->next && con->next->type!=con->type)) { - clear= 1; - Mat4CpyMat4(oldmat, ob->obmat); - - /* If we have several inputs, do a blend of them */ - if (tot) { - if (tot>1) { - if (a) { - for (i=0; i<3; i++) { - asize[i]=1.0f + (asize[i]/(a)); - aloc[i]=(aloc[i]/a); - } - - NormalQuat(aquat); - - QuatToMat3(aquat, rmat); - SizeToMat3(asize, smat); - Mat3MulMat3(mat, rmat, smat); - Mat4CpyMat3(focusmat, mat); - VECCOPY(focusmat[3], aloc); - - evaluate_constraint(con, ob, obtype, obdata, focusmat); - } - - } - /* If we only have one, blend with the current obmat */ - else { - float solution[4][4]; - float delta[4][4]; - float imat[4][4]; - float identity[4][4]; - - /* solve the constraint then blend it to the previous one */ - evaluate_constraint(con, ob, obtype, obdata, lastmat); - - Mat4CpyMat4 (solution, ob->obmat); - - /* Interpolate the enforcement */ - Mat4Invert (imat, oldmat); - Mat4MulMat4 (delta, solution, imat); - - if (a<1.0) { - Mat4One(identity); - Mat4BlendMat4(delta, identity, delta, a); - } - Mat4MulMat4 (ob->obmat, delta, oldmat); - } - } - } - } } /* for calculation of the inverse parent transform, only used for editor */ void what_does_parent(Object *ob) { - clear_workob(); Mat4One(workob.obmat); Mat4One(workob.parentinv); + Mat4One(workob.constinv); workob.parent= ob->parent; workob.track= ob->track; @@ -1868,7 +1968,7 @@ void what_does_parent(Object *ob) workob.constraints.first = ob->constraints.first; workob.constraints.last = ob->constraints.last; - strcpy (workob.parsubstr, ob->parsubstr); + strcpy(workob.parsubstr, ob->parsubstr); where_is_object(&workob); } @@ -2071,8 +2171,28 @@ void object_handle_update(Object *ob) where_is_pose(ob); } } + + if(ob->particlesystem.first) { + ParticleSystem *tpsys, *psys; + + psys= ob->particlesystem.first; + while(psys) { + if(psys->flag & PSYS_ENABLED) { + particle_system_update(ob, psys); + psys= psys->next; + } + else if(psys->flag & PSYS_DELETE) { + tpsys=psys->next; + BLI_remlink(&ob->particlesystem, psys); + psys_free(ob,psys); + psys= tpsys; + } + else + psys= psys->next; + } + } } - + /* the no-group proxy case, we call update */ if(ob->proxy && ob->proxy_group==NULL) { /* set pointer in library proxy target, for copying, but restore it */ |