static int lupdate(lua_State *L) { struct particle_system *ps = (struct particle_system *)lua_touserdata(L, 1); float dt = (float)luaL_checknumber(L, 2); struct matrix *anchor = (struct matrix*)lua_touserdata(L, 3); int edge = (int)luaL_checkinteger(L, 4); if (ps->config->positionType == POSITION_TYPE_GROUPED) { ps->config->emitterMatrix = anchor; } else { ps->config->emitterMatrix = NULL; } ps->config->sourcePosition.x = 0; ps->config->sourcePosition.y = 0; particle_system_update(ps, dt); if (ps->isActive || ps->isAlive) { int n = ps->particleCount; int i; struct matrix tmp; for (i = 0; i < n; i++) { struct particle *p = &ps->particles[i]; calc_particle_system_mat(p, &ps->matrix[i], edge); if (ps->config->positionType != POSITION_TYPE_GROUPED) { memcpy(tmp.m, &ps->matrix[i], sizeof(int) * 6); matrix_mul(&ps->matrix[i], &tmp, anchor); } p->color_val = color4f(&p->color); } lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); } return 1; }
/* saves the current emitter state for a particle system and calculates particles */ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int UNUSED(numVerts), ModifierApplyFlag flag) { DerivedMesh *dm = derivedData; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; ParticleSystem *psys = NULL; bool needsFree = false; /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */ if (ob->particlesystem.first) psys = psmd->psys; else return; if (!psys_check_enabled(ob, psys, (flag & MOD_APPLY_RENDER) != 0)) return; if (dm == NULL) { dm = get_dm(ob, NULL, NULL, vertexCos, false, true); if (!dm) return; needsFree = true; } /* clear old dm */ if (psmd->dm_final) { psmd->dm_final->needsFree = true; psmd->dm_final->release(psmd->dm_final); if (psmd->dm_deformed) { psmd->dm_deformed->needsFree = 1; psmd->dm_deformed->release(psmd->dm_deformed); psmd->dm_deformed = NULL; } } else if (psmd->flag & eParticleSystemFlag_file_loaded) { /* in file read dm just wasn't saved in file so no need to reset everything */ psmd->flag &= ~eParticleSystemFlag_file_loaded; } else { /* no dm before, so recalc particles fully */ psys->recalc |= PSYS_RECALC_RESET; } /* make new dm */ psmd->dm_final = CDDM_copy(dm); CDDM_apply_vert_coords(psmd->dm_final, vertexCos); CDDM_calc_normals(psmd->dm_final); if (needsFree) { dm->needsFree = true; dm->release(dm); } /* protect dm */ psmd->dm_final->needsFree = false; DM_ensure_tessface(psmd->dm_final); if (!psmd->dm_final->deformedOnly) { /* XXX Think we can assume here that if current DM is not only-deformed, ob->deformedOnly has been set. * This is awfully weak though. :| */ if (ob->derivedDeform) { psmd->dm_deformed = CDDM_copy(ob->derivedDeform); } else { /* Can happen in some cases, e.g. when rendering from Edit mode... */ psmd->dm_deformed = CDDM_from_mesh((Mesh *)ob->data); } DM_ensure_tessface(psmd->dm_deformed); } /* report change in mesh structure */ if (psmd->dm_final->getNumVerts(psmd->dm_final) != psmd->totdmvert || psmd->dm_final->getNumEdges(psmd->dm_final) != psmd->totdmedge || psmd->dm_final->getNumTessFaces(psmd->dm_final) != psmd->totdmface) { psys->recalc |= PSYS_RECALC_RESET; psmd->totdmvert = psmd->dm_final->getNumVerts(psmd->dm_final); psmd->totdmedge = psmd->dm_final->getNumEdges(psmd->dm_final); psmd->totdmface = psmd->dm_final->getNumTessFaces(psmd->dm_final); } if (!(ob->transflag & OB_NO_PSYS_UPDATE)) { psmd->flag &= ~eParticleSystemFlag_psys_updated; particle_system_update(md->scene, ob, psys, (flag & MOD_APPLY_RENDER) != 0); psmd->flag |= eParticleSystemFlag_psys_updated; } }
void BKE_object_handle_data_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { ID *data_id = (ID *)ob->data; AnimData *adt = BKE_animdata_from_id(data_id); Key *key; float ctime = BKE_scene_frame_get(scene); if (G.debug & G_DEBUG_DEPSGRAPH) printf("recalcdata %s\n", ob->id.name + 2); /* TODO(sergey): Only used by legacy depsgraph. */ if (adt) { /* evaluate drivers - datalevel */ /* XXX: for mesh types, should we push this to derivedmesh instead? */ BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS); } /* TODO(sergey): Only used by legacy depsgraph. */ key = BKE_key_from_object(ob); if (key && key->block.first) { if (!(ob->shapeflag & OB_SHAPE_LOCK)) BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS); } /* includes all keys and modifiers */ switch (ob->type) { case OB_MESH: { BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL; uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH; #ifdef WITH_FREESTYLE /* make sure Freestyle edge/face marks appear in DM for render (see T40315) */ if (eval_ctx->mode != DAG_EVAL_VIEWPORT) { data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; } #endif if (em) { makeDerivedMesh(scene, ob, em, data_mask, false); /* was CD_MASK_BAREMESH */ } else { makeDerivedMesh(scene, ob, NULL, data_mask, false); } break; } case OB_ARMATURE: if (ob->id.lib && ob->proxy_from) { if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) { printf("Proxy copy error, lib Object: %s proxy Object: %s\n", ob->id.name + 2, ob->proxy_from->id.name + 2); } } else { BKE_pose_where_is(scene, ob); } break; case OB_MBALL: BKE_displist_make_mball(eval_ctx, scene, ob); break; case OB_CURVE: case OB_SURF: case OB_FONT: BKE_displist_make_curveTypes(scene, ob, 0); break; case OB_LATTICE: BKE_lattice_modifiers_calc(scene, ob); break; case OB_EMPTY: if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data) if (BKE_image_is_animated(ob->data)) BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0); break; } /* related materials */ /* XXX: without depsgraph tagging, this will always need to be run, which will be slow! * However, not doing anything (or trying to hack around this lack) is not an option * anymore, especially due to Cycles [#31834] */ if (ob->totcol) { int a; if (ob->totcol != 0) { BLI_mutex_lock(&material_lock); for (a = 1; a <= ob->totcol; a++) { Material *ma = give_current_material(ob, a); if (ma) { /* recursively update drivers for this material */ material_drivers_update(scene, ma, ctime); } } BLI_mutex_unlock(&material_lock); } } else if (ob->type == OB_LAMP) lamp_drivers_update(scene, ob->data, ctime); /* particles */ if (ob != scene->obedit && ob->particlesystem.first) { ParticleSystem *tpsys, *psys; DerivedMesh *dm; ob->transflag &= ~OB_DUPLIPARTS; psys = ob->particlesystem.first; while (psys) { /* ensure this update always happens even if psys is disabled */ if (psys->recalc & PSYS_RECALC_TYPE) { psys_changed_type(ob, psys); } if (psys_check_enabled(ob, psys)) { /* check use of dupli objects here */ if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->mode == DAG_EVAL_RENDER) && ((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob) || (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group))) { ob->transflag |= OB_DUPLIPARTS; } particle_system_update(scene, 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; } if (eval_ctx->mode == DAG_EVAL_RENDER && ob->transflag & OB_DUPLIPARTS) { /* this is to make sure we get render level duplis in groups: * the derivedmesh must be created before init_render_mesh, * since object_duplilist does dupliparticles before that */ CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL; dm = mesh_create_derived_render(scene, ob, data_mask); dm->release(dm); for (psys = ob->particlesystem.first; psys; psys = psys->next) psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated; } } /* quick cache removed */ }
/* saves the current emitter state for a particle system and calculates particles */ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int UNUSED(numVerts), ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = derivedData; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; ParticleSystem *psys = NULL; int needsFree = 0; /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */ if (ob->particlesystem.first) psys = psmd->psys; else return; if (!psys_check_enabled(ob, psys)) return; if (dm == NULL) { dm = get_dm(ob, NULL, NULL, vertexCos, false, true); if (!dm) return; needsFree = 1; } /* clear old dm */ if (psmd->dm) { psmd->dm->needsFree = 1; psmd->dm->release(psmd->dm); } else if (psmd->flag & eParticleSystemFlag_file_loaded) { /* in file read dm just wasn't saved in file so no need to reset everything */ psmd->flag &= ~eParticleSystemFlag_file_loaded; } else { /* no dm before, so recalc particles fully */ psys->recalc |= PSYS_RECALC_RESET; } /* make new dm */ psmd->dm = CDDM_copy(dm); CDDM_apply_vert_coords(psmd->dm, vertexCos); CDDM_calc_normals(psmd->dm); if (needsFree) { dm->needsFree = 1; dm->release(dm); } /* protect dm */ psmd->dm->needsFree = 0; /* report change in mesh structure */ DM_ensure_tessface(psmd->dm); if (psmd->dm->getNumVerts(psmd->dm) != psmd->totdmvert || psmd->dm->getNumEdges(psmd->dm) != psmd->totdmedge || psmd->dm->getNumTessFaces(psmd->dm) != psmd->totdmface) { psys->recalc |= PSYS_RECALC_RESET; psmd->totdmvert = psmd->dm->getNumVerts(psmd->dm); psmd->totdmedge = psmd->dm->getNumEdges(psmd->dm); psmd->totdmface = psmd->dm->getNumTessFaces(psmd->dm); } if (!(ob->transflag & OB_NO_PSYS_UPDATE)) { psmd->flag &= ~eParticleSystemFlag_psys_updated; particle_system_update(md->scene, ob, psys); psmd->flag |= eParticleSystemFlag_psys_updated; } }