/* unlike VIEW3D_OT_view_selected this is for framing a render and not * meant to take into account vertex/bone selection for eg. */ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); Object *camera_ob= v3d->camera; float r_co[3]; /* the new location to apply */ /* this function does all the important stuff */ if (camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co)) { ObjectTfmProtectedChannels obtfm; float obmat_new[4][4]; copy_m4_m4(obmat_new, camera_ob->obmat); copy_v3_v3(obmat_new[3], r_co); /* only touch location */ object_tfm_protected_backup(camera_ob, &obtfm); object_apply_mat4(camera_ob, obmat_new, TRUE, TRUE); object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D); /* notifiers */ DAG_id_tag_update(&camera_ob->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, camera_ob); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
// a shortened version of parent_set_exec() // if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) { Object workob; Main *bmain = CTX_data_main(C); Scene *sce = CTX_data_scene(C); if (!par || bc_test_parent_loop(par, ob)) return false; ob->parent = par; ob->partype = PAROBJECT; ob->parsubstr[0] = 0; if (is_parent_space) { float mat[4][4]; // calc par->obmat where_is_object(sce, par); // move child obmat into world space mul_m4_m4m4(mat, ob->obmat, par->obmat); copy_m4_m4(ob->obmat, mat); } // apply child obmat (i.e. decompose it into rot/loc/size) object_apply_mat4(ob, ob->obmat, 0, 0); // compute parentinv what_does_parent(sce, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA; par->recalc |= OB_RECALC_OB; DAG_scene_sort(bmain, sce); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); return true; }
Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, Object *par_ob, bool is_library_node) { Object *obn = copy_object(source_ob); obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; scene_add_base(sce, obn); if (instance_node) { anim_importer.read_node_transform(instance_node, obn); // if we also have a source_node (always ;), take its // transformation matrix and apply it to the newly instantiated // object to account for node hierarchy transforms in // .dae if(source_node) { COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix(); COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order float mat[4][4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { mat[i][j] = bmat4[i][j]; } } // calc new matrix and apply mul_m4_m4m4(obn->obmat, mat, obn->obmat); object_apply_mat4(obn, obn->obmat, 0, 0); } } else { anim_importer.read_node_transform(source_node, obn); } DAG_scene_sort(CTX_data_main(mContext), sce); DAG_ids_flush_update(CTX_data_main(mContext), 0); COLLADAFW::NodePointerArray &children = source_node->getChildNodes(); if (children.getCount()) { for (unsigned int i = 0; i < children.getCount(); i++) { COLLADAFW::Node *child_node = children[i]; const COLLADAFW::UniqueId& child_id = child_node->getUniqueId(); if (object_map.find(child_id) == object_map.end()) continue; COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes(); Object *new_child = NULL; if (inodes.getCount()) { // \todo loop through instance nodes const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId(); new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, NULL, is_library_node); } else { new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, NULL, is_library_node); } bc_set_parent(new_child, obn, mContext, true); if (is_library_node) libnode_ob.push_back(new_child); } } // when we have an instance_node, don't return the object, because otherwise // its correct location gets overwritten in write_node(). Fixes bug #26012. if(instance_node) { if (par_ob && obn) bc_set_parent(obn, par_ob, mContext); return NULL; } else return obn; }
void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid, TransformReader *tm) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); ((ArmatureModifierData *)md)->object = ob_arm; copy_m4_m4(ob->obmat, bind_shape_matrix); object_apply_mat4(ob, ob->obmat, 0, 0); #if 1 bc_set_parent(ob, ob_arm, C); #else Object workob; ob->parent = ob_arm; ob->partype = PAROBJECT; what_does_parent(scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); #endif ((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP; // create all vertex groups std::vector<JointData>::iterator it; int joint_index; for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) { const char *name = "Group"; // skip joints that have invalid UID if ((*it).joint_uid == COLLADAFW::UniqueId::INVALID) continue; // name group by joint node name if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) { name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]); } ED_vgroup_add_name(ob, (char*)name); } // <vcount> - number of joints per vertex - joints_per_vertex // <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender? // for each vertex in weight indices // for each bone index in vertex // add vertex to group at group index // treat group index -1 specially // get def group by index with BLI_findlink for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) { unsigned int limit = weight + joints_per_vertex[vertex]; for ( ; weight < limit; weight++) { int joint = joint_indices[weight], joint_weight = weight_indices[weight]; // -1 means "weight towards the bind shape", we just don't assign it to any group if (joint != -1) { bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint); ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE); } } } }