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:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_bparticles.c')
-rw-r--r--source/blender/modifiers/intern/MOD_bparticles.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/source/blender/modifiers/intern/MOD_bparticles.c b/source/blender/modifiers/intern/MOD_bparticles.c
new file mode 100644
index 00000000000..6ef04684593
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_bparticles.c
@@ -0,0 +1,227 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 by the Blender Foundation.
+ * All rights reserved.
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_bparticles.c
+ * \ingroup modifiers
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_lib_query.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_scene.h"
+
+#include "BLI_math.h"
+
+#include "MOD_bparticles.h"
+#include "MOD_util.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+typedef struct RuntimeData {
+ BParticlesSimulationState simulation_state;
+ float last_simulated_frame;
+} RuntimeData;
+
+static RuntimeData *get_or_create_runtime_struct(BParticlesModifierData *bpmd)
+{
+ if (bpmd->modifier.runtime == NULL) {
+ RuntimeData *runtime = MEM_callocN(sizeof(RuntimeData), __func__);
+ runtime->simulation_state = NULL;
+ runtime->last_simulated_frame = 0.0f;
+ bpmd->modifier.runtime = runtime;
+ }
+
+ return bpmd->modifier.runtime;
+}
+
+static RuntimeData *get_runtime_struct(BParticlesModifierData *bpmd)
+{
+ return bpmd->modifier.runtime;
+}
+
+static void free_runtime_data(RuntimeData *runtime)
+{
+ BParticles_simulation_free(runtime->simulation_state);
+ MEM_freeN(runtime);
+}
+
+static void free_modifier_runtime_data(BParticlesModifierData *bpmd)
+{
+ RuntimeData *runtime = (RuntimeData *)bpmd->modifier.runtime;
+ if (runtime != NULL) {
+ free_runtime_data(runtime);
+ bpmd->modifier.runtime = NULL;
+ }
+}
+
+BParticlesSimulationState MOD_bparticles_find_simulation_state(Object *object)
+{
+ BLI_assert(object != NULL);
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)modifiers_findByType(
+ object, eModifierType_BParticles);
+ if (bpmd == NULL) {
+ return NULL;
+ }
+ RuntimeData *runtime = get_runtime_struct(bpmd);
+ if (runtime == NULL) {
+ return NULL;
+ }
+ return runtime->simulation_state;
+}
+
+static Mesh *applyModifier(ModifierData *md, const struct ModifierEvalContext *ctx, Mesh *mesh)
+{
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+ BParticlesModifierData *bpmd_orig = (BParticlesModifierData *)modifier_get_original(
+ &bpmd->modifier);
+
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ float current_frame = BKE_scene_frame_get(scene);
+
+ RuntimeData *runtime = get_or_create_runtime_struct(bpmd);
+
+ if (runtime->simulation_state == NULL) {
+ runtime->simulation_state = BParticles_new_simulation();
+ }
+
+ if (current_frame == runtime->last_simulated_frame) {
+ /* do nothing */
+ }
+ else if (current_frame == runtime->last_simulated_frame + 1.0f) {
+ BParticles_simulate_modifier(bpmd, ctx->depsgraph, runtime->simulation_state, 1.0f / FPS);
+ runtime->last_simulated_frame = current_frame;
+ }
+ else {
+ free_modifier_runtime_data(bpmd);
+ runtime = get_or_create_runtime_struct(bpmd);
+ runtime->simulation_state = BParticles_new_simulation();
+ runtime->last_simulated_frame = current_frame;
+ BParticles_modifier_free_cache(bpmd_orig);
+
+ BParticles_simulate_modifier(bpmd, ctx->depsgraph, runtime->simulation_state, 0.0f);
+ runtime->last_simulated_frame = current_frame;
+ }
+
+ if (bpmd->output_type == MOD_BPARTICLES_OUTPUT_POINTS) {
+ return BParticles_modifier_point_mesh_from_state(runtime->simulation_state);
+ }
+ else if (bpmd->output_type == MOD_BPARTICLES_OUTPUT_TETRAHEDONS) {
+ Mesh *new_mesh = BParticles_modifier_mesh_from_state(runtime->simulation_state);
+ BKE_mesh_copy_settings(new_mesh, mesh);
+ return new_mesh;
+ }
+ else {
+ return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+ }
+}
+
+static void initData(ModifierData *UNUSED(md))
+{
+}
+
+static void freeData(ModifierData *md)
+{
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+ free_modifier_runtime_data(bpmd);
+ BParticles_modifier_free_cache(bpmd);
+}
+
+static void copyData(const ModifierData *md, ModifierData *target, const int flag)
+{
+ BParticlesModifierData *tbpmd = (BParticlesModifierData *)target;
+
+ modifier_copyData_generic(md, target, flag);
+ tbpmd->num_cached_frames = 0;
+ tbpmd->cached_frames = NULL;
+}
+
+static void freeRuntimeData(void *runtime_data_v)
+{
+ if (runtime_data_v == NULL) {
+ return;
+ }
+ RuntimeData *runtime = (RuntimeData *)runtime_data_v;
+ free_runtime_data(runtime);
+}
+
+static bool dependsOnTime(ModifierData *UNUSED(md))
+{
+ return true;
+}
+
+static void updateDepsgraph(ModifierData *UNUSED(md),
+ const ModifierUpdateDepsgraphContext *UNUSED(ctx))
+{
+}
+
+static void foreachObjectLink(ModifierData *UNUSED(md),
+ Object *UNUSED(ob),
+ ObjectWalkFunc UNUSED(walk),
+ void *UNUSED(userData))
+{
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ BParticlesModifierData *bpmd = (BParticlesModifierData *)md;
+ walk(userData, ob, (ID **)&bpmd->node_tree, IDWALK_CB_NOP);
+
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+}
+
+ModifierTypeInfo modifierType_BParticles = {
+ /* name */ "BParticles",
+ /* structName */ "BParticlesModifierData",
+ /* structSize */ sizeof(BParticlesModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh,
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ freeRuntimeData,
+};