Alembic import: fixed bug where local matrix from Alembic was used as object matrix
authorSybren A. Stüvel <sybren@stuvel.eu>
Thu, 23 Feb 2017 15:00:06 +0000 (16:00 +0100)
committerSybren A. Stüvel <sybren@stuvel.eu>
Thu, 6 Apr 2017 14:04:31 +0000 (16:04 +0200)
Also renamed AbcObjectReader::readObjectMatrix to
setupObjectTransform, as it does more than just reading the object
matrix; it also sets up an object constraint if the Alembic Xform is
animated.

source/blender/alembic/intern/abc_object.cc
source/blender/alembic/intern/abc_object.h
source/blender/alembic/intern/alembic_capi.cc

index 0b2c8cb6b8a19b80a886a1303cd6b43b91aa109c..62042d255011d815da266df838f60fddc8fa58c5 100644 (file)
@@ -214,7 +214,7 @@ Imath::M44d get_matrix(const IXformSchema &schema, const float time)
        return s0.getMatrix();
 }
 
-void AbcObjectReader::readObjectMatrix(const float time)
+void AbcObjectReader::setupObjectTransform(const float time)
 {
        bool is_constant = false;
 
@@ -292,6 +292,16 @@ void AbcObjectReader::read_matrix(float mat[4][4], const float time, const float
        const Imath::M44d matrix = get_matrix(schema, time);
        convert_matrix(matrix, m_object, mat, scale, has_alembic_parent);
 
+       if (has_alembic_parent) {
+               /* In this case, the matrix in Alembic is in local coordinates, so
+                * convert to world matrix. To prevent us from reading and accumulating
+                * all parent matrices in the Alembic file, we assume that the Blender
+                * parent object is already updated for the current timekey, and use its
+                * world matrix. */
+               BLI_assert(m_object->parent);
+               mul_m4_m4m4(mat, m_object->parent->obmat, mat);
+       }
+
        is_constant = schema.isConstant();
 }
 
index 6d97c0359b7365231aa1d2c913c30017cf9daced..5b7663943c29a4fd20303bfed9e40983a2c1f8a2 100644 (file)
@@ -183,7 +183,8 @@ public:
                return dm;
        }
 
-       void readObjectMatrix(const float time);
+       /** Reads the object matrix and sets up an object transform if animated. */
+       void setupObjectTransform(const float time);
 
        void addCacheModifier();
 
index 44d902907c3ebc551371199018dfcb202e5f420b..44f495428281ee4154384e4c0be05994138be08b 100644 (file)
@@ -639,7 +639,6 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
 
                if (reader->valid()) {
                        reader->readObjectData(data->bmain, 0.0f);
-                       reader->readObjectMatrix(0.0f);
 
                        min_time = std::min(min_time, reader->minTime());
                        max_time = std::max(max_time, reader->maxTime());
@@ -712,6 +711,12 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
                        return;
                }
        }
+
+       /* Setup transformations and constraints. */
+       for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+               AbcObjectReader *reader = *iter;
+               reader->setupObjectTransform(0.0f);
+       }
 }
 
 static void import_endjob(void *user_data)