Alembic import: fix scene min/max time computation to take objects with
[blender.git] / source / blender / alembic / intern / abc_transform.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Esteban Tovagliari, Cedric Paille, Kevin Dietrich
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 #include "abc_transform.h"
24
25 #include <OpenEXR/ImathBoxAlgo.h>
26
27 #include "abc_util.h"
28
29 extern "C" {
30 #include "DNA_object_types.h"
31
32 #include "BLI_math.h"
33
34 #include "BKE_object.h"
35 }
36
37 using Alembic::AbcGeom::OObject;
38 using Alembic::AbcGeom::OXform;
39
40 /* ************************************************************************** */
41
42 static bool has_parent_camera(Object *ob)
43 {
44         if (!ob->parent) {
45                 return false;
46         }
47
48         Object *parent = ob->parent;
49
50         if (parent->type == OB_CAMERA) {
51                 return true;
52         }
53
54         return has_parent_camera(parent);
55 }
56
57 /* ************************************************************************** */
58
59 AbcTransformWriter::AbcTransformWriter(Object *ob,
60                                        const OObject &abc_parent,
61                                        AbcTransformWriter *parent,
62                                        unsigned int time_sampling,
63                                        ExportSettings &settings)
64     : AbcObjectWriter(NULL, ob, time_sampling, settings, parent)
65 {
66         m_is_animated = hasAnimation(m_object);
67         m_parent = NULL;
68
69         if (!m_is_animated) {
70                 time_sampling = 0;
71         }
72
73         m_xform = OXform(abc_parent, get_id_name(m_object), time_sampling);
74         m_schema = m_xform.getSchema();
75 }
76
77 void AbcTransformWriter::do_write()
78 {
79         if (m_first_frame) {
80                 m_visibility = Alembic::AbcGeom::CreateVisibilityProperty(m_xform, m_xform.getSchema().getTimeSampling());
81         }
82
83         m_visibility.set(!(m_object->restrictflag & OB_RESTRICT_VIEW));
84
85         if (!m_first_frame && !m_is_animated) {
86                 return;
87         }
88
89         float mat[4][4];
90         create_transform_matrix(m_object, mat);
91
92         /* Only apply rotation to root camera, parenting will propagate it. */
93         if (m_object->type == OB_CAMERA && !has_parent_camera(m_object)) {
94                 float rot_mat[4][4];
95                 unit_m4(rot_mat);
96                 rotate_m4(rot_mat, 'X', -M_PI_2);
97                 mul_m4_m4m4(mat, mat, rot_mat);
98         }
99
100         if (!m_object->parent) {
101                 /* Only apply scaling to root objects, parenting will propagate it. */
102                 float scale_mat[4][4];
103                 scale_m4_fl(scale_mat, m_settings.global_scale);
104                 mul_m4_m4m4(mat, mat, scale_mat);
105                 mul_v3_fl(mat[3], m_settings.global_scale);
106         }
107
108         m_matrix = convert_matrix(mat);
109
110         m_sample.setMatrix(m_matrix);
111         m_schema.set(m_sample);
112 }
113
114 Imath::Box3d AbcTransformWriter::bounds()
115 {
116         Imath::Box3d bounds;
117
118         for (int i = 0; i < m_children.size(); ++i) {
119                 Imath::Box3d box(m_children[i]->bounds());
120                 bounds.extendBy(box);
121         }
122
123         return Imath::transform(bounds, m_matrix);
124 }
125
126 bool AbcTransformWriter::hasAnimation(Object */*ob*/) const
127 {
128         /* TODO(kevin): implement this. */
129         return true;
130 }
131
132 /* ************************************************************************** */
133
134 AbcEmptyReader::AbcEmptyReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
135     : AbcObjectReader(object, settings)
136 {
137         Alembic::AbcGeom::IXform xform(object, Alembic::AbcGeom::kWrapExisting);
138         m_schema = xform.getSchema();
139
140         get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
141 }
142
143 bool AbcEmptyReader::valid() const
144 {
145         return m_schema.valid();
146 }
147
148 void AbcEmptyReader::readObjectData(Main *bmain, float /*time*/)
149 {
150         m_object = BKE_object_add_only_object(bmain, OB_EMPTY, m_object_name.c_str());
151         m_object->data = NULL;
152 }