[Bf-blender-cvs] [5a48a83] alembic_pointcache: Integration of point caching into the modifier stack.
Lukas Tönne
noreply at git.blender.org
Tue Nov 4 13:49:50 CET 2014
Commit: 5a48a83663ffb4a03a63d9af95b3270988b1d006
Author: Lukas Tönne
Date: Tue Nov 4 13:46:52 2014 +0100
Branches: alembic_pointcache
https://developer.blender.org/rB5a48a83663ffb4a03a63d9af95b3270988b1d006
Integration of point caching into the modifier stack.
This ensures that the modifier stack is disabled up to the last valid
cache modifier. This cache modifier then provides a derived mesh as
input for the remaining modifier stack tail, or as final output if no
other modifiers follow.
===================================================================
M source/blender/blenkernel/intern/DerivedMesh.c
M source/blender/pointcache/PTC_api.cpp
M source/blender/pointcache/PTC_api.h
M source/blender/pointcache/intern/reader.cpp
M source/blender/pointcache/intern/reader.h
===================================================================
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 81c03d8..1956a03 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -65,6 +65,8 @@
#include "BKE_deform.h"
#include "BKE_global.h" /* For debug flag, DM_update_tessface_data() func. */
+#include "PTC_api.h"
+
#ifdef WITH_GAMEENGINE
#include "BKE_navmesh_conversion.h"
static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
@@ -1461,6 +1463,58 @@ static void dm_ensure_display_normals(DerivedMesh *dm)
CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
}
}
+
+/* Look for last point cache modifier that provides a valid derived mesh.
+ * This will then be used as the input for remaining modifiers, or as the
+ * final result if no other modifiers follow.
+ */
+static ModifierData *mesh_find_start_modifier(Scene *scene, Object *ob, VirtualModifierData *virtual_modifiers, int required_mode, bool useDeform)
+{
+ const bool skipVirtualArmature = (useDeform < 0);
+
+ ModifierData *md;
+
+ for (md = ob->modifiers.last; md; md = md->prev) {
+ if (md->type == eModifierType_PointCache) {
+ PointCacheModifierData *pcmd = (PointCacheModifierData *)md;
+ struct PTCReader *reader;
+ PTCReadSampleResult result;
+
+ if (!modifier_isEnabled(scene, md, required_mode))
+ continue;
+
+ /* XXX needs a more lightweight reader stored inside the modifier,
+ * which can be checked quickly for valid cache samples before reading.
+ */
+ reader = PTC_reader_point_cache(scene, ob, pcmd);
+ result = PTC_test_sample(reader, scene->r.cfra);
+ PTC_reader_free(reader);
+
+ if (ELEM(result, PTC_READ_SAMPLE_EXACT, PTC_READ_SAMPLE_INTERPOLATED)) {
+ break;
+ }
+ }
+ }
+ if (md)
+ return md;
+
+ /* no valid cache modifier found,
+ * take virtual modifiers at list start into account
+ */
+
+ if (!skipVirtualArmature) {
+ md = modifiers_getVirtualModifierList(ob, virtual_modifiers);
+ }
+ else {
+ /* game engine exception */
+ md = ob->modifiers.first;
+ if (md && md->type == eModifierType_Armature)
+ md = md->next;
+ }
+
+ return md;
+}
+
/* new value for useDeform -1 (hack for the gameengine):
* - apply only the modifier stack of the object, skipping the virtual modifiers,
* - don't apply the key
@@ -1482,7 +1536,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
int numVerts = me->totvert;
int required_mode;
bool isPrevDeform = false;
- const bool skipVirtualArmature = (useDeform < 0);
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
const bool has_multires = (mmd && mmd->sculptlvl != 0);
bool multires_applied = false;
@@ -1511,23 +1564,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
app_flags |= MOD_APPLY_USECACHE;
if (useDeform)
deform_app_flags |= MOD_APPLY_USECACHE;
-
- if (!skipVirtualArmature) {
- firstmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
- }
- else {
- /* game engine exception */
- firstmd = ob->modifiers.first;
- if (firstmd && firstmd->type == eModifierType_Armature)
- firstmd = firstmd->next;
- }
-
- md = firstmd;
-
- modifiers_clearErrors(ob);
-
+
if (useRenderParams) required_mode = eModifierMode_Render;
else required_mode = eModifierMode_Realtime;
+
+ modifiers_clearErrors(ob);
+
+ firstmd = mesh_find_start_modifier(scene, ob, &virtualModifierData, required_mode, useDeform);
+ md = firstmd;
if (do_mod_wmcol || do_mod_mcol) {
/* Find the last active modifier generating a preview, or NULL if none. */
diff --git a/source/blender/pointcache/PTC_api.cpp b/source/blender/pointcache/PTC_api.cpp
index ac57661..8e730e0 100644
--- a/source/blender/pointcache/PTC_api.cpp
+++ b/source/blender/pointcache/PTC_api.cpp
@@ -77,12 +77,6 @@ void PTC_reader_free(PTCReader *_reader)
delete reader;
}
-PTCReadSampleResult PTC_read_sample(struct PTCReader *_reader, float frame)
-{
- PTC::Reader *reader = (PTC::Reader *)_reader;
- return reader->read_sample(frame);
-}
-
void PTC_reader_get_frame_range(PTCReader *_reader, int *start_frame, int *end_frame)
{
PTC::Reader *reader = (PTC::Reader *)_reader;
@@ -92,6 +86,18 @@ void PTC_reader_get_frame_range(PTCReader *_reader, int *start_frame, int *end_f
if (end_frame) *end_frame = efra;
}
+PTCReadSampleResult PTC_read_sample(PTCReader *_reader, float frame)
+{
+ PTC::Reader *reader = (PTC::Reader *)_reader;
+ return reader->read_sample(frame);
+}
+
+PTCReadSampleResult PTC_test_sample(PTCReader *_reader, float frame)
+{
+ PTC::Reader *reader = (PTC::Reader *)_reader;
+ return reader->test_sample(frame);
+}
+
/* get writer/reader from RNA type */
PTCWriter *PTC_writer_from_rna(Scene *scene, PointerRNA *ptr)
{
diff --git a/source/blender/pointcache/PTC_api.h b/source/blender/pointcache/PTC_api.h
index c60138a..1861e1d 100644
--- a/source/blender/pointcache/PTC_api.h
+++ b/source/blender/pointcache/PTC_api.h
@@ -57,8 +57,9 @@ void PTC_writer_free(struct PTCWriter *writer);
void PTC_write_sample(struct PTCWriter *writer);
void PTC_reader_free(struct PTCReader *reader);
-PTCReadSampleResult PTC_read_sample(struct PTCReader *reader, float frame);
void PTC_reader_get_frame_range(struct PTCReader *reader, int *start_frame, int *end_frame);
+PTCReadSampleResult PTC_read_sample(struct PTCReader *reader, float frame);
+PTCReadSampleResult PTC_test_sample(struct PTCReader *reader, float frame);
/* get writer/reader from RNA type */
struct PTCWriter *PTC_writer_from_rna(struct Scene *scene, struct PointerRNA *ptr);
diff --git a/source/blender/pointcache/intern/reader.cpp b/source/blender/pointcache/intern/reader.cpp
index b6a8a74..e54926a 100644
--- a/source/blender/pointcache/intern/reader.cpp
+++ b/source/blender/pointcache/intern/reader.cpp
@@ -62,4 +62,29 @@ ISampleSelector Reader::get_frame_sample_selector(float frame)
return ISampleSelector(frame_to_time(frame), ISampleSelector::kFloorIndex);
}
+PTCReadSampleResult Reader::test_sample(float frame)
+{
+ if (m_archive.valid()) {
+ double start_time, end_time;
+ GetArchiveStartAndEndTime(m_archive, start_time, end_time);
+ float start_frame = time_to_frame(start_time);
+ float end_frame = time_to_frame(end_time);
+
+ if (frame < start_frame)
+ return PTC_READ_SAMPLE_EARLY;
+ else if (frame > end_frame)
+ return PTC_READ_SAMPLE_LATE;
+ else {
+ /* TODO could also be EXACT, but INTERPOLATED is more general
+ * do we need to support this?
+ * checking individual time samplings is also possible, but more involved.
+ */
+ return PTC_READ_SAMPLE_INTERPOLATED;
+ }
+ }
+ else {
+ return PTC_READ_SAMPLE_INVALID;
+ }
+}
+
} /* namespace PTC */
diff --git a/source/blender/pointcache/intern/reader.h b/source/blender/pointcache/intern/reader.h
index 8ee27bc..3b2bd1d 100644
--- a/source/blender/pointcache/intern/reader.h
+++ b/source/blender/pointcache/intern/reader.h
@@ -43,6 +43,7 @@ public:
void get_frame_range(int &start_frame, int &end_frame);
Abc::ISampleSelector get_frame_sample_selector(float frame);
+ PTCReadSampleResult test_sample(float frame);
virtual PTCReadSampleResult read_sample(float frame) = 0;
protected:
More information about the Bf-blender-cvs
mailing list