------------------------------------------------------------------------------------------------
| 147 | |
| 148 | // ------------------------------------------------------------------------------------------------ |
| 149 | void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier, |
| 150 | const Scene & /*in*/, |
| 151 | const Object &orig_object) { |
| 152 | // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() |
| 153 | const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier); |
| 154 | ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror); |
| 155 | std::shared_ptr<Object> mirror_ob = mir.mirror_ob.lock(); |
| 156 | |
| 157 | conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes); |
| 158 | |
| 159 | // XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ... |
| 160 | |
| 161 | // take all input meshes and clone them |
| 162 | for (unsigned int i = 0; i < out.mNumMeshes; ++i) { |
| 163 | aiMesh *mesh; |
| 164 | SceneCombiner::Copy(&mesh, conv_data.meshes[out.mMeshes[i]]); |
| 165 | |
| 166 | const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f; |
| 167 | const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f; |
| 168 | const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f; |
| 169 | |
| 170 | if (mirror_ob) { |
| 171 | const aiVector3D center(mirror_ob->obmat[3][0], mirror_ob->obmat[3][1], mirror_ob->obmat[3][2]); |
| 172 | for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { |
| 173 | aiVector3D &v = mesh->mVertices[j]; |
| 174 | |
| 175 | v.x = center.x + xs * (center.x - v.x); |
| 176 | v.y = center.y + ys * (center.y - v.y); |
| 177 | v.z = center.z + zs * (center.z - v.z); |
| 178 | } |
| 179 | } else { |
| 180 | for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { |
| 181 | aiVector3D &v = mesh->mVertices[j]; |
| 182 | v.x *= xs; |
| 183 | v.y *= ys; |
| 184 | v.z *= zs; |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | if (mesh->mNormals) { |
| 189 | for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { |
| 190 | aiVector3D &v = mesh->mNormals[j]; |
| 191 | v.x *= xs; |
| 192 | v.y *= ys; |
| 193 | v.z *= zs; |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | if (mesh->mTangents) { |
| 198 | for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { |
| 199 | aiVector3D &v = mesh->mTangents[j]; |
| 200 | v.x *= xs; |
| 201 | v.y *= ys; |
| 202 | v.z *= zs; |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | if (mesh->mBitangents) { |
no test coverage detected