static int edbm_inset_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); InsetData *opdata; float mlen[2]; float center_3d[3]; if (!edbm_inset_init(C, op, true)) { return OPERATOR_CANCELLED; } opdata = op->customdata; /* initialize mouse values */ if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; } mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_inset_calc(op); edbm_inset_update_header(op, C); WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
void ED_object_base_init_from_view(bContext *C, Base *base) { View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); Object *ob= base->object; if (scene==NULL) return; if (v3d==NULL) { base->lay = scene->lay; VECCOPY(ob->loc, scene->cursor); } else { if (v3d->localvd) { base->lay= ob->lay= v3d->layact | v3d->lay; VECCOPY(ob->loc, v3d->cursor); } else { base->lay= ob->lay= v3d->layact; VECCOPY(ob->loc, scene->cursor); } if (U.flag & USER_ADD_VIEWALIGNED) { RegionView3D *rv3d = CTX_wm_region_view3d(C); if(rv3d) { rv3d->viewquat[0]= -rv3d->viewquat[0]; QuatToEul(rv3d->viewquat, ob->rot); rv3d->viewquat[0]= -rv3d->viewquat[0]; } } } where_is_object(scene, ob); }
bool paint_curve_poll(bContext *C) { Object *ob = CTX_data_active_object(C); Paint *p; RegionView3D *rv3d = CTX_wm_region_view3d(C); SpaceImage *sima; if (rv3d && !(ob && ((ob->mode & OB_MODE_ALL_PAINT) != 0))) { return false; } sima = CTX_wm_space_image(C); if (sima && sima->mode != SI_MODE_PAINT) { return false; } p = BKE_paint_get_active_from_context(C); if (p && p->brush && (p->brush->flag & BRUSH_CURVE)) { return true; } return false; }
static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event) { /* TODO make modal keymap (see fly mode) */ RegionView3D *rv3d = CTX_wm_region_view3d(C); BevelData *opdata; float center_3d[3]; if (!edbm_bevel_init(C, op, true)) { return OPERATOR_CANCELLED; } opdata = op->customdata; /* initialize mouse values */ if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; } edbm_bevel_calc_initial_length(op, event, false); /* for OFFSET_VALUE only, the scale is the size of a pixel under the mouse in 3d space */ opdata->scale[OFFSET_VALUE] = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_bevel_update_header(C, op); if (!edbm_bevel_calc(op)) { edbm_bevel_cancel(C, op); return OPERATOR_CANCELLED; } WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op)) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); ObjectTfmProtectedChannels obtfm; copy_qt_qt(rv3d->lviewquat, rv3d->viewquat); rv3d->lview= rv3d->view; if(rv3d->persp != RV3D_CAMOB) { rv3d->lpersp= rv3d->persp; } object_tfm_protected_backup(v3d->camera, &obtfm); ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist); object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag); DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB); rv3d->persp = RV3D_CAMOB; WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, v3d->camera); return OPERATOR_FINISHED; }
static bool depthdropper_poll(bContext *C) { PointerRNA ptr; PropertyRNA *prop; int index_dummy; uiBut *but; /* check if there's an active button taking depth value */ if ((CTX_wm_window(C) != NULL) && (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) && (but->type == UI_BTYPE_NUM) && (prop != NULL)) { if ((RNA_property_type(prop) == PROP_FLOAT) && (RNA_property_subtype(prop) & PROP_UNIT_LENGTH) && (RNA_property_array_check(prop) == false)) { return 1; } } else { RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d && rv3d->persp == RV3D_CAMOB) { View3D *v3d = CTX_wm_view3d(C); if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) { return 1; } } } return 0; }
/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; int depth_test_enabled; if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } GPU_matrix_push(); if (t->spacetype == SPACE_VIEW3D) { /* pass */ } else if (t->spacetype == SPACE_IMAGE) { GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]); } else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) { /* only scale y */ rcti *mask = &t->ar->v2d.mask; rctf *datamask = &t->ar->v2d.cur; float xsize = BLI_rctf_size_x(datamask); float ysize = BLI_rctf_size_y(datamask); float xmask = BLI_rcti_size_x(mask); float ymask = BLI_rcti_size_y(mask); GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask)); } depth_test_enabled = GPU_depth_test_enabled(); if (depth_test_enabled) { GPU_depth_test(false); } uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor(TH_GRID); set_inverted_drawing(1); imm_drawcircball(t->center_global, t->prop_size, imat, pos); set_inverted_drawing(0); immUnbindProgram(); if (depth_test_enabled) { GPU_depth_test(true); } GPU_matrix_pop(); } }
static int render_view3d_changed(RenderEngine *engine, const bContext *C) { ARegion *ar = CTX_wm_region(C); Render *re; int update = 0; char name[32]; sprintf(name, "View3dPreview %p", (void *)ar); re = RE_GetRender(name); if (re) { RegionView3D *rv3d = CTX_wm_region_view3d(C); View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); rctf viewplane, viewplane1; rcti disprect, disprect1; float mat[4][4]; float clipsta, clipend; bool orth; if (engine->update_flag & RE_ENGINE_UPDATE_MA) update |= PR_UPDATE_MATERIAL; if (engine->update_flag & RE_ENGINE_UPDATE_OTHER) update |= PR_UPDATE_MATERIAL; engine->update_flag = 0; if (engine->resolution_x != ar->winx || engine->resolution_y != ar->winy) update |= PR_UPDATE_RENDERSIZE; RE_GetView(re, mat); if (compare_m4m4(mat, rv3d->viewmat, 0.00001f) == 0) { update |= PR_UPDATE_VIEW; } render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth); RE_GetViewPlane(re, &viewplane1, &disprect1); if (BLI_rctf_compare(&viewplane, &viewplane1, 0.00001f) == 0) update |= PR_UPDATE_VIEW; render_view3d_disprect(scene, ar, v3d, rv3d, &disprect); if (BLI_rcti_compare(&disprect, &disprect1) == 0) update |= PR_UPDATE_RENDERSIZE; if (update) engine->flag |= RE_ENGINE_DO_UPDATE; //if (update) // printf("changed ma %d res %d view %d\n", update & PR_UPDATE_MATERIAL, update & PR_UPDATE_RENDERSIZE, update & PR_UPDATE_VIEW); } return update; }
static int view3d_camera_to_view_poll(bContext *C) { View3D *v3d= CTX_wm_view3d(C); if(v3d && v3d->camera && v3d->camera->id.lib==NULL) { RegionView3D *rv3d= CTX_wm_region_view3d(C); if(rv3d && !rv3d->viewlock) { return 1; } } return 0; }
/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; float center[3]; int depth_test_enabled; UI_ThemeColor(TH_GRID); if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } glPushMatrix(); copy_v3_v3(center, t->center); if ((t->spacetype == SPACE_VIEW3D) && t->obedit) { mul_m4_v3(t->obedit->obmat, center); /* because t->center is in local space */ } else if (t->spacetype == SPACE_IMAGE) { float aspx, aspy; if (t->options & CTX_MASK) { /* untested - mask aspect is TODO */ ED_space_image_get_aspect(t->sa->spacedata.first, &aspx, &aspy); } else { ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); } glScalef(1.0f / aspx, 1.0f / aspy, 1.0); } depth_test_enabled = glIsEnabled(GL_DEPTH_TEST); if (depth_test_enabled) glDisable(GL_DEPTH_TEST); set_inverted_drawing(1); drawcircball(GL_LINE_LOOP, center, t->prop_size, imat); set_inverted_drawing(0); if (depth_test_enabled) glEnable(GL_DEPTH_TEST); glPopMatrix(); } }
static void render_view3d_do(RenderEngine *engine, const bContext *C) { wmJob *wm_job; RenderPreview *rp; Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); int width = ar->winx, height = ar->winy; int divider = 1; int resolution_threshold = scene->r.preview_start_resolution * scene->r.preview_start_resolution; if (CTX_wm_window(C) == NULL) return; if (!render_view3d_flag_changed(engine, C)) return; wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview", WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); rp = MEM_callocN(sizeof(RenderPreview), "render preview"); rp->job = wm_job; while (width * height > resolution_threshold) { width = max_ii(1, width / 2); height = max_ii(1, height / 2); divider *= 2; } /* customdata for preview thread */ rp->scene = scene; rp->engine = engine; rp->sa = CTX_wm_area(C); rp->ar = CTX_wm_region(C); rp->v3d = rp->sa->spacedata.first; rp->rv3d = CTX_wm_region_view3d(C); rp->bmain = CTX_data_main(C); rp->resolution_divider = divider; rp->start_resolution_divider = divider; rp->has_freestyle = (scene->r.mode & R_EDGE_FRS) != 0; copy_m4_m4(rp->viewmat, rp->rv3d->viewmat); /* clear info text */ engine->text[0] = '\0'; /* setup job */ WM_jobs_customdata_set(wm_job, rp, render_view3d_free); WM_jobs_timer(wm_job, 0.1, NC_SPACE | ND_SPACE_VIEW3D, NC_SPACE | ND_SPACE_VIEW3D); WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL); WM_jobs_start(CTX_wm_manager(C), wm_job); engine->flag &= ~RE_ENGINE_DO_UPDATE; }
void ED_object_rotation_from_view(bContext *C, float *rot) { RegionView3D *rv3d= CTX_wm_region_view3d(C); if(rv3d) { float quat[4]; copy_qt_qt(quat, rv3d->viewquat); quat[0]= -quat[0]; quat_to_eul(rot, quat); } else { zero_v3(rot); } }
/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; int depth_test_enabled; UI_ThemeColor(TH_GRID); if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } glPushMatrix(); if (t->spacetype == SPACE_VIEW3D) { /* pass */ } else if (t->spacetype == SPACE_IMAGE) { glScalef(1.0f / t->aspect[0], 1.0f / t->aspect[1], 1.0f); } else if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) { /* only scale y */ rcti *mask = &t->ar->v2d.mask; rctf *datamask = &t->ar->v2d.cur; float xsize = BLI_rctf_size_x(datamask); float ysize = BLI_rctf_size_y(datamask); float xmask = BLI_rcti_size_x(mask); float ymask = BLI_rcti_size_y(mask); glScalef(1.0f, (ysize / xsize) * (xmask / ymask), 1.0f); } depth_test_enabled = glIsEnabled(GL_DEPTH_TEST); if (depth_test_enabled) glDisable(GL_DEPTH_TEST); set_inverted_drawing(1); drawcircball(GL_LINE_LOOP, t->center_global, t->prop_size, imat); set_inverted_drawing(0); if (depth_test_enabled) glEnable(GL_DEPTH_TEST); glPopMatrix(); } }
static int view3d_camera_to_view_selected_poll(bContext *C) { View3D *v3d= CTX_wm_view3d(C); if(v3d && v3d->camera && v3d->camera->id.lib==NULL) { RegionView3D *rv3d= CTX_wm_region_view3d(C); if(rv3d) { if (rv3d->is_persp == FALSE) { CTX_wm_operator_poll_msg_set(C, "Only valid for a perspective camera view"); } else if (!rv3d->viewlock) { return 1; } } } return 0; }
static int depthdropper_init(bContext *C, wmOperator *op) { int index_dummy; SpaceType *st; ARegionType *art; st = BKE_spacetype_from_id(SPACE_VIEW3D); art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW); DepthDropper *ddr = MEM_callocN(sizeof(DepthDropper), __func__); uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy); /* fallback to the active camera's dof */ if (ddr->prop == NULL) { RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d && rv3d->persp == RV3D_CAMOB) { View3D *v3d = CTX_wm_view3d(C); if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) { RNA_id_pointer_create(v3d->camera->data, &ddr->ptr); ddr->prop = RNA_struct_find_property(&ddr->ptr, "dof_distance"); ddr->is_undo = true; } } } else { ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO); } if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) || (RNA_property_editable(&ddr->ptr, ddr->prop) == false) || (RNA_property_type(ddr->prop) != PROP_FLOAT)) { MEM_freeN(ddr); return false; } op->customdata = ddr; ddr->art = art; ddr->draw_handle_pixel = ED_region_draw_cb_activate( art, depthdropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL); ddr->init_depth = RNA_property_float_get(&ddr->ptr, ddr->prop); return true; }
static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); int ret; if (em->bm->totedgesel == 0) { BKE_report(op->reports, RPT_ERROR, "Selected edges/faces required"); return OPERATOR_CANCELLED; } /* if the properties are set or there is no rv3d, * skip model and exec immediately */ if ((CTX_wm_region_view3d(C) == NULL) || (RNA_struct_property_is_set(op->ptr, "plane_co") && RNA_struct_property_is_set(op->ptr, "plane_no"))) { return mesh_bisect_exec(C, op); } ret = WM_gesture_straightline_invoke(C, op, event); if (ret & OPERATOR_RUNNING_MODAL) { View3D *v3d = CTX_wm_view3d(C); wmGesture *gesture = op->customdata; BisectData *opdata; opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data"); opdata->mesh_backup = EDBM_redo_state_store(em); opdata->is_first = true; gesture->userdata = opdata; /* misc other vars */ G.moving = G_TRANSFORM_EDIT; opdata->twtype = v3d->twtype; v3d->twtype = 0; /* initialize modal callout */ ED_area_headerprint(CTX_wm_area(C), IFACE_("LMB: Click and drag to draw cut line")); } return ret; }
/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; float center[3]; UI_ThemeColor(TH_GRID); if(t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } glPushMatrix(); VECCOPY(center, t->center); if((t->spacetype == SPACE_VIEW3D) && t->obedit) { mul_m4_v3(t->obedit->obmat, center); /* because t->center is in local space */ } else if(t->spacetype == SPACE_IMAGE) { float aspx, aspy; ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); glScalef(1.0f/aspx, 1.0f/aspy, 1.0); } set_inverted_drawing(1); drawcircball(GL_LINE_LOOP, center, t->prop_size, imat); set_inverted_drawing(0); glPopMatrix(); } }
static int view3d_setcameratoview_exec(bContext *C, wmOperator *UNUSED(op)) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); copy_qt_qt(rv3d->lviewquat, rv3d->viewquat); rv3d->lview= rv3d->view; if(rv3d->persp != RV3D_CAMOB) { rv3d->lpersp= rv3d->persp; } ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist); DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB); rv3d->persp = RV3D_CAMOB; WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, v3d->camera); return OPERATOR_FINISHED; }
static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op) { RegionView3D *rv3d = CTX_wm_region_view3d(C); Object *obedit = CTX_data_edit_object(C); EditBone *bone; float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3]; char name[MAXBONENAME]; RNA_string_get(op->ptr, "name", name); copy_v3_v3(curs, ED_view3d_cursor3d_get(CTX_data_scene(C), CTX_wm_view3d(C))); /* Get inverse point for head and orientation for tail */ invert_m4_m4(obedit->imat, obedit->obmat); mul_m4_v3(obedit->imat, curs); if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) copy_m3_m4(obmat, rv3d->viewmat); else unit_m3(obmat); copy_m3_m4(viewmat, obedit->obmat); mul_m3_m3m3(totmat, obmat, viewmat); invert_m3_m3(imat, totmat); ED_armature_deselect_all(obedit); /* Create a bone */ bone = ED_armature_edit_bone_add(obedit->data, name); copy_v3_v3(bone->head, curs); if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) add_v3_v3v3(bone->tail, bone->head, imat[1]); // bone with unit length 1 else add_v3_v3v3(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); return OPERATOR_FINISHED; }
static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_data) { wmJob *wm_job; RenderPreview *rp; Scene *scene = CTX_data_scene(C); if (CTX_wm_window(C) == NULL) { engine->flag |= RE_ENGINE_DO_UPDATE; return; } wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview", WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); rp = MEM_callocN(sizeof(RenderPreview), "render preview"); /* customdata for preview thread */ rp->scene = scene; rp->engine = engine; rp->sa = CTX_wm_area(C); rp->ar = CTX_wm_region(C); rp->v3d = rp->sa->spacedata.first; rp->rv3d = CTX_wm_region_view3d(C); rp->bmain = CTX_data_main(C); rp->keep_data = keep_data; copy_m4_m4(rp->viewmat, rp->rv3d->viewmat); /* dont alloc in threads */ if (engine->text == NULL) engine->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext"); /* setup job */ WM_jobs_customdata_set(wm_job, rp, render_view3d_free); WM_jobs_timer(wm_job, 0.1, NC_SPACE | ND_SPACE_VIEW3D, NC_SPACE | ND_SPACE_VIEW3D); WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL); WM_jobs_start(CTX_wm_manager(C), wm_job); engine->flag &= ~RE_ENGINE_DO_UPDATE; }
static int depthdropper_init(bContext *C, wmOperator *op) { DepthDropper *ddr; int index_dummy; SpaceType *st; ARegionType *art; st = BKE_spacetype_from_id(SPACE_VIEW3D); art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW); op->customdata = ddr = MEM_callocN(sizeof(DepthDropper), "DepthDropper"); UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy); /* fallback to the active camera's dof */ if (ddr->prop == NULL) { RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d && rv3d->persp == RV3D_CAMOB) { View3D *v3d = CTX_wm_view3d(C); if (v3d->camera && v3d->camera->data && (((ID *)v3d->camera->data)->lib == NULL)) { RNA_id_pointer_create(v3d->camera->data, &ddr->ptr); ddr->prop = RNA_struct_find_property(&ddr->ptr, "dof_distance"); } } } if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) || (RNA_property_editable(&ddr->ptr, ddr->prop) == false) || (RNA_property_type(ddr->prop) != PROP_FLOAT)) { return false; } ddr->art = art; ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, depthdropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL); return true; }
static void render_view3d_do(RenderEngine *engine, const bContext *C) { wmJob *wm_job; RenderPreview *rp; Scene *scene = CTX_data_scene(C); if (CTX_wm_window(C) == NULL) return; if (!render_view3d_flag_changed(engine, C)) return; wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview", WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); rp = MEM_callocN(sizeof(RenderPreview), "render preview"); rp->job = wm_job; /* customdata for preview thread */ rp->scene = scene; rp->engine = engine; rp->sa = CTX_wm_area(C); rp->ar = CTX_wm_region(C); rp->v3d = rp->sa->spacedata.first; rp->rv3d = CTX_wm_region_view3d(C); rp->bmain = CTX_data_main(C); rp->resolution_divider = START_RESOLUTION_DIVIDER; copy_m4_m4(rp->viewmat, rp->rv3d->viewmat); /* clear info text */ engine->text[0] = '\0'; /* setup job */ WM_jobs_customdata_set(wm_job, rp, render_view3d_free); WM_jobs_timer(wm_job, 0.1, NC_SPACE | ND_SPACE_VIEW3D, NC_SPACE | ND_SPACE_VIEW3D); WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL); WM_jobs_start(CTX_wm_manager(C), wm_job); engine->flag &= ~RE_ENGINE_DO_UPDATE; }
static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); BevelData *opdata; float center_3d[3]; if (!edbm_bevel_init(C, op, true)) { return OPERATOR_CANCELLED; } opdata = op->customdata; /* initialize mouse values */ if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEDIAN, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; } /* for OFFSET_VALUE only, the scale is the size of a pixel under the mouse in 3d space */ opdata->scale[OFFSET_VALUE] = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; /* since we are affecting untransformed object but seeing in transformed space, * compensate for that */ opdata->scale[OFFSET_VALUE] /= opdata->max_obj_scale; edbm_bevel_calc_initial_length(op, event, false); edbm_bevel_update_header(C, op); if (!edbm_bevel_calc(op)) { edbm_bevel_cancel(C, op); ED_workspace_status_text(C, NULL); return OPERATOR_CANCELLED; } WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); FlyInfo *fly; if (rv3d->viewlock) return OPERATOR_CANCELLED; fly = MEM_callocN(sizeof(FlyInfo), "FlyOperation"); op->customdata = fly; if (initFlyInfo(C, fly, op, event) == false) { MEM_freeN(op->customdata); return OPERATOR_CANCELLED; } flyEvent(fly, event); WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
/****** walk operator ******/ static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); WalkInfo *walk; if (rv3d->viewlock & RV3D_LOCKED) return OPERATOR_CANCELLED; walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation"); op->customdata = walk; if (initWalkInfo(C, walk, op) == false) { MEM_freeN(op->customdata); return OPERATOR_CANCELLED; } walkEvent(C, op, walk, event); WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
static int object_armature_add_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); int newob= 0; int enter_editmode; unsigned int layer; float loc[3], rot[3]; object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) return OPERATOR_CANCELLED; if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) { obedit= ED_object_add_type(C, OB_ARMATURE, loc, rot, TRUE, layer); ED_object_enter_editmode(C, 0); newob = 1; } else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); if(obedit==NULL) { BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature."); return OPERATOR_CANCELLED; } /* v3d and rv3d are allowed to be NULL */ add_primitive_bone(CTX_data_scene(C), v3d, rv3d); /* userdef */ if (newob && !enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); RAS_Rect area_rect; area_rect.SetLeft(cam_frame->xmin); area_rect.SetBottom(cam_frame->ymin); area_rect.SetRight(cam_frame->xmax); area_rect.SetTop(cam_frame->ymax); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name+2; char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); #ifdef WITH_PYTHON resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path setGamePythonPath(G.main->name); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ #endif bgl::InitExtensions(true); // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; // Globals to be carried on over blender files GlobalSettings gs; gs.matmode= startscene->gm.matmode; gs.glslflag= startscene->gm.flag; do { View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); #ifdef WITH_PYTHON bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); #endif bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE; bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES; if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */ // create the canvas, rasterizer and rendertools RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar); // default mouse state set on render panel if (mouse_state) canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); RAS_IRenderTools* rendertools = new KX_BlenderRenderTools(); RAS_IRasterizer* rasterizer = NULL; if(displaylists) { if (GLEW_VERSION_1_1 && !novertexarrays) rasterizer = new RAS_ListRasterizer(canvas, true, true); else rasterizer = new RAS_ListRasterizer(canvas); } else if (GLEW_VERSION_1_1 && !novertexarrays) rasterizer = new RAS_VAOpenGLRasterizer(canvas, false); else rasterizer = new RAS_OpenGLRasterizer(canvas); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); // create a networkdevice NG_NetworkDeviceInterface* networkdevice = new NG_LoopBackNetworkDeviceInterface(); // // create a ketsji/blendersystem (only needed for timing and stuff) KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); // create the ketsjiengine KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); // set the devices ketsjiengine->SetKeyboardDevice(keyboarddevice); ketsjiengine->SetMouseDevice(mousedevice); ketsjiengine->SetNetworkDevice(networkdevice); ketsjiengine->SetCanvas(canvas); ketsjiengine->SetRenderTools(rendertools); ketsjiengine->SetRasterizer(rasterizer); ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif //lock frame and camera enabled - storing global values int tmp_lay= startscene->lay; Object *tmp_camera = startscene->camera; if (v3d->scenelock==0){ startscene->lay= v3d->lay; startscene->camera= v3d->camera; } // some blender stuff float camzoom; int draw_letterbox = 0; if(rv3d->persp==RV3D_CAMOB) { if(startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ camzoom = 1.0f; draw_letterbox = 1; } else { camzoom = 1.0 / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); } } else { camzoom = 2.0; } ketsjiengine->SetDrawType(v3d->drawtype); ketsjiengine->SetCameraZoom(camzoom); // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (exitstring != "") strcpy(basedpath, exitstring.Ptr()); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[242]; strcpy(temppath, "//"); strcat(temppath, basedpath); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if(blenderdata) { BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); if (scene) { int startFrame = scene->r.cfra; ketsjiengine->SetAnimRecordMode(animation_record, startFrame); // Quad buffered needs a special window. if(scene->gm.stereoflag == STEREO_ENABLED){ if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); rasterizer->SetEyeSeparation(scene->gm.eyeseparation); } rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f); } if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { if (rv3d->persp != RV3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); if(rv3d->persp == RV3D_ORTHO) { ketsjiengine->SetCameraOverrideClipping(-v3d->far, v3d->far); } else { ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); } ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); sceneconverter->addInitFromFrame=false; if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); bool usemat = false, useglslmat = false; if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; if(GPU_glsl_support()) useglslmat = true; else if(gs.matmode == GAME_MAT_GLSL) usemat = false; if(usemat && (gs.matmode != GAME_MAT_TEXFACE)) sceneconverter->SetMaterials(true); if(useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, networkdevice, startscenename, scene, canvas); #ifdef WITH_PYTHON // some python things PyObject *gameLogic, *gameLogic_keys; setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); #endif // WITH_PYTHON //initialize Dome Settings if(scene->gm.stereoflag == STEREO_DOME) ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext); // initialize 3D Audio Settings AUD_I3DDevice* dev = AUD_get3DDevice(); if(dev) { dev->setSpeedOfSound(scene->audio.speed_of_sound); dev->setDopplerFactor(scene->audio.doppler_factor); dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); } // from see blender.c: // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (blenderdata->versionfile < 250) do_versions_ipos_to_animato(blenderdata); if (sceneconverter) { // convert and add scene sceneconverter->ConvertScene( startscene, rendertools, canvas); ketsjiengine->AddScene(startscene); // init the rasterizer rasterizer->Init(); // start the engine ketsjiengine->StartEngine(true); // Set the animation playback rate for ipo's and actions // the framerate below should patch with FPS macro defined in blendef.h // Could be in StartEngine set the framerate, we need the scene to do this ketsjiengine->SetAnimFrameRate(FPS); // the mainloop printf("\nBlender Game Engine Started\n"); while (!exitrequested) { // first check if we want to exit exitrequested = ketsjiengine->GetExitCode(); // kick the engine bool render = ketsjiengine->NextFrame(); if (render) { if(draw_letterbox) { // Clear screen to border color // We do this here since we set the canvas to be within the frames. This means the engine // itself is unaware of the extra space, so we clear the whole region for it. glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f); glViewport(ar->winrct.xmin, ar->winrct.ymin, ar->winrct.xmax - ar->winrct.xmin, ar->winrct.ymax - ar->winrct.ymin); glClear(GL_COLOR_BUFFER_BIT); } // render the frame ketsjiengine->Render(); } wm_window_process_events_nosleep(); // test for the ESC key //XXX while (qtest()) while(wmEvent *event= (wmEvent *)win->queue.first) { short val = 0; //unsigned short event = 0; //XXX extern_qread(&val); if (keyboarddevice->ConvertBlenderEvent(event->type,event->val)) exitrequested = KX_EXIT_REQUEST_BLENDER_ESC; /* Coordinate conversion... where * should this really be? */ if (event->type==MOUSEMOVE) { /* Note, not nice! XXX 2.5 event hack */ val = event->x - ar->winrct.xmin; mousedevice->ConvertBlenderEvent(MOUSEX, val); val = ar->winy - (event->y - ar->winrct.ymin) - 1; mousedevice->ConvertBlenderEvent(MOUSEY, val); } else { mousedevice->ConvertBlenderEvent(event->type,event->val); } BLI_remlink(&win->queue, event); wm_event_free(event); } if(win != CTX_wm_window(C)) { exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */ } } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop #ifdef WITH_PYTHON // Clears the dictionary by hand: // This prevents, extra references to global variables // inside the GameLogic dictionary when the python interpreter is finalized. // which allows the scene to safely delete them :) // see: (space.c)->start_game //PyDict_Clear(PyModule_GetDict(gameLogic)); // Keep original items, means python plugins will autocomplete members PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); Py_ssize_t listIndex; for (listIndex=0; listIndex < numitems; listIndex++) { PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); if (!PySequence_Contains(gameLogic_keys, item)) { PyDict_DelItem( PyModule_GetDict(gameLogic), item); } } Py_DECREF(gameLogic_keys_new); gameLogic_keys_new = NULL; #endif ketsjiengine->StopEngine(); #ifdef WITH_PYTHON exitGamePythonScripting(); #endif networkdevice->Disconnect(); } if (sceneconverter) { delete sceneconverter; sceneconverter = NULL; } #ifdef WITH_PYTHON Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; #endif } //lock frame and camera enabled - restoring global values if (v3d->scenelock==0){ startscene->lay= tmp_lay; startscene->camera= tmp_camera; } if(exitrequested != KX_EXIT_REQUEST_OUTSIDE) { // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); } // clean up some stuff if (ketsjiengine) { delete ketsjiengine; ketsjiengine = NULL; } if (kxsystem) { delete kxsystem; kxsystem = NULL; } if (networkdevice) { delete networkdevice; networkdevice = NULL; } if (keyboarddevice) { delete keyboarddevice; keyboarddevice = NULL; } if (mousedevice) { delete mousedevice; mousedevice = NULL; } if (rasterizer) { delete rasterizer; rasterizer = NULL; } if (rendertools) { delete rendertools; rendertools = NULL; } if (canvas) { delete canvas; canvas = NULL; } // stop all remaining playing sounds AUD_getDevice()->stopAll(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (!disableVBO) U.gameflags &= ~USER_DISABLE_VBO; if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); #ifdef WITH_PYTHON Py_DECREF(pyGlobalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ struct wmWindowManager *wm= CTX_wm_manager(C); struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); RAS_Rect area_rect; area_rect.SetLeft(cam_frame->xmin); area_rect.SetBottom(cam_frame->ymin); area_rect.SetRight(cam_frame->xmax); area_rect.SetTop(cam_frame->ymax); int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; Main* blenderdata = maggie1; char* startscenename = startscene->id.name+2; char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); BLI_strncpy(oldsce, G.main->name, sizeof(oldsce)); #ifdef WITH_PYTHON resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path setGamePythonPath(G.main->name); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */ #endif bgl::InitExtensions(true); // VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; // Globals to be carried on over blender files GlobalSettings gs; gs.matmode= startscene->gm.matmode; gs.glslflag= startscene->gm.flag; do { View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0) && GPU_display_list_support(); #ifdef WITH_PYTHON bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0); #endif // bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0); bool mouse_state = (startscene->gm.flag & GAME_SHOW_MOUSE) != 0; bool restrictAnimFPS = (startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES) != 0; short drawtype = v3d->drawtype; /* we do not support material mode in game engine, force change to texture mode */ if (drawtype == OB_MATERIAL) drawtype = OB_TEXTURE; if (animation_record) usefixed= false; /* override since you don't want to run full-speed for sim recording */ // create the canvas and rasterizer RAS_ICanvas* canvas = new KX_BlenderCanvas(wm, win, area_rect, ar); // default mouse state set on render panel if (mouse_state) canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); else canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); // Setup vsync int previous_vsync = 0; canvas->GetSwapInterval(previous_vsync); if (startscene->gm.vsync == VSYNC_ADAPTIVE) canvas->SetSwapInterval(-1); else canvas->SetSwapInterval((startscene->gm.vsync == VSYNC_ON) ? 1 : 0); RAS_IRasterizer* rasterizer = NULL; //Don't use displaylists with VBOs //If auto starts using VBOs, make sure to check for that here if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO) rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage); else rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage); RAS_IRasterizer::MipmapOption mipmapval = rasterizer->GetMipmapping(); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); // create a networkdevice NG_NetworkDeviceInterface* networkdevice = new NG_LoopBackNetworkDeviceInterface(); // // create a ketsji/blendersystem (only needed for timing and stuff) KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); // create the ketsjiengine KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); // set the devices ketsjiengine->SetKeyboardDevice(keyboarddevice); ketsjiengine->SetMouseDevice(mousedevice); ketsjiengine->SetNetworkDevice(networkdevice); ketsjiengine->SetCanvas(canvas); ketsjiengine->SetRasterizer(rasterizer); ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif //lock frame and camera enabled - storing global values int tmp_lay= startscene->lay; Object *tmp_camera = startscene->camera; if (v3d->scenelock==0) { startscene->lay= v3d->lay; startscene->camera= v3d->camera; } // some blender stuff float camzoom; int draw_letterbox = 0; if (rv3d->persp==RV3D_CAMOB) { if (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */ camzoom = 1.0f; draw_letterbox = 1; } else { camzoom = 1.0f / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); } } else { camzoom = 2.0; } rasterizer->SetDrawingMode(drawtype); ketsjiengine->SetCameraZoom(camzoom); // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) { exitrequested = KX_EXIT_REQUEST_NO_REQUEST; if (bfd) BLO_blendfiledata_free(bfd); char basedpath[FILE_MAX]; // base the actuator filename with respect // to the original file working directory if (exitstring != "") BLI_strncpy(basedpath, exitstring.ReadPtr(), sizeof(basedpath)); // load relative to the last loaded file, this used to be relative // to the first file but that makes no sense, relative paths in // blend files should be relative to that file, not some other file // that happened to be loaded first BLI_path_abs(basedpath, pathname); bfd = load_game_data(basedpath); // if it wasn't loaded, try it forced relative if (!bfd) { // just add "//" in front of it char temppath[FILE_MAX] = "//"; BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2); BLI_path_abs(temppath, pathname); bfd = load_game_data(temppath); } // if we got a loaded blendfile, proceed if (bfd) { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; if (blenderdata) { BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); #ifdef WITH_PYTHON setGamePythonPath(G.main->name); #endif } } // else forget it, we can't find it else { exitrequested = KX_EXIT_REQUEST_QUIT_GAME; } } Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2); if (scene) { int startFrame = scene->r.cfra; ketsjiengine->SetAnimRecordMode(animation_record, startFrame); // Quad buffered needs a special window. if (scene->gm.stereoflag == STEREO_ENABLED) { if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode); rasterizer->SetEyeSeparation(scene->gm.eyeseparation); } rasterizer->SetBackColor(scene->gm.framing.col); } if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { if (rv3d->persp != RV3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat)); ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat)); ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); bool usemat = false, useglslmat = false; if (GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; if (GPU_glsl_support()) useglslmat = true; else if (gs.matmode == GAME_MAT_GLSL) usemat = false; if (usemat) sceneconverter->SetMaterials(true); if (useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); if (scene->gm.flag & GAME_NO_MATERIAL_CACHING) sceneconverter->SetCacheMaterials(false); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, networkdevice, startscenename, scene, canvas); #ifdef WITH_PYTHON // some python things PyObject *gameLogic, *gameLogic_keys; setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL); #endif // WITH_PYTHON //initialize Dome Settings if (scene->gm.stereoflag == STEREO_DOME) ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext); // initialize 3D Audio Settings AUD_I3DDevice* dev = AUD_get3DDevice(); if (dev) { dev->setSpeedOfSound(scene->audio.speed_of_sound); dev->setDopplerFactor(scene->audio.doppler_factor); dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model)); } // from see blender.c: // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (blenderdata->versionfile < 250) do_versions_ipos_to_animato(blenderdata); if (sceneconverter) { // convert and add scene sceneconverter->ConvertScene( startscene, rasterizer, canvas); ketsjiengine->AddScene(startscene); // init the rasterizer rasterizer->Init(); // start the engine ketsjiengine->StartEngine(true); // Set the animation playback rate for ipo's and actions // the framerate below should patch with FPS macro defined in blendef.h // Could be in StartEngine set the framerate, we need the scene to do this ketsjiengine->SetAnimFrameRate(FPS); #ifdef WITH_PYTHON char *python_main = NULL; pynextframestate.state = NULL; pynextframestate.func = NULL; python_main = KX_GetPythonMain(scene); // the mainloop printf("\nBlender Game Engine Started\n"); if (python_main) { char *python_code = KX_GetPythonCode(blenderdata, python_main); if (python_code) { ketsjinextframestate.ketsjiengine = ketsjiengine; ketsjinextframestate.C = C; ketsjinextframestate.win = win; ketsjinextframestate.scene = scene; ketsjinextframestate.ar = ar; ketsjinextframestate.keyboarddevice = keyboarddevice; ketsjinextframestate.mousedevice = mousedevice; ketsjinextframestate.draw_letterbox = draw_letterbox; pynextframestate.state = &ketsjinextframestate; pynextframestate.func = &BL_KetsjiPyNextFrame; printf("Yielding control to Python script '%s'...\n", python_main); PyRun_SimpleString(python_code); printf("Exit Python script '%s'\n", python_main); MEM_freeN(python_code); } } else #endif /* WITH_PYTHON */ { while (!exitrequested) { exitrequested = BL_KetsjiNextFrame(ketsjiengine, C, win, scene, ar, keyboarddevice, mousedevice, draw_letterbox); } } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); #ifdef WITH_PYTHON if (python_main) MEM_freeN(python_main); #endif /* WITH_PYTHON */ gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop #ifdef WITH_PYTHON // Clears the dictionary by hand: // This prevents, extra references to global variables // inside the GameLogic dictionary when the python interpreter is finalized. // which allows the scene to safely delete them :) // see: (space.c)->start_game //PyDict_Clear(PyModule_GetDict(gameLogic)); // Keep original items, means python plugins will autocomplete members PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic)); const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new); Py_ssize_t listIndex; for (listIndex=0; listIndex < numitems; listIndex++) { PyObject *item = PyList_GET_ITEM(gameLogic_keys_new, listIndex); if (!PySequence_Contains(gameLogic_keys, item)) { PyDict_DelItem( PyModule_GetDict(gameLogic), item); } } Py_DECREF(gameLogic_keys_new); gameLogic_keys_new = NULL; #endif ketsjiengine->StopEngine(); #ifdef WITH_PYTHON exitGamePythonScripting(); #endif networkdevice->Disconnect(); } if (sceneconverter) { delete sceneconverter; sceneconverter = NULL; } #ifdef WITH_PYTHON Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; #endif } //lock frame and camera enabled - restoring global values if (v3d->scenelock==0) { startscene->lay= tmp_lay; startscene->camera= tmp_camera; } if (exitrequested != KX_EXIT_REQUEST_OUTSIDE) { // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); // set mipmap setting back to its original value rasterizer->SetMipmapping(mipmapval); } // clean up some stuff if (ketsjiengine) { delete ketsjiengine; ketsjiengine = NULL; } if (kxsystem) { delete kxsystem; kxsystem = NULL; } if (networkdevice) { delete networkdevice; networkdevice = NULL; } if (keyboarddevice) { delete keyboarddevice; keyboarddevice = NULL; } if (mousedevice) { delete mousedevice; mousedevice = NULL; } if (rasterizer) { delete rasterizer; rasterizer = NULL; } if (canvas) { canvas->SetSwapInterval(previous_vsync); // Set the swap interval back delete canvas; canvas = NULL; } // stop all remaining playing sounds AUD_getDevice()->stopAll(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); if (!disableVBO) U.gameflags &= ~USER_DISABLE_VBO; if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name)); #ifdef WITH_PYTHON Py_DECREF(pyGlobalDict); // Release Python's GIL PyGILState_Release(gilstate); #endif }
static int armature_calc_roll_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_edit_object(C); const short type = RNA_enum_get(op->ptr, "type"); const short axis_only = RNA_boolean_get(op->ptr, "axis_only"); const short axis_flip = RNA_boolean_get(op->ptr, "axis_flip"); float imat[3][3]; bArmature *arm = ob->data; EditBone *ebone; copy_m3_m4(imat, ob->obmat); invert_m3(imat); if (type == CALC_ROLL_CURSOR) { /* Cursor */ Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; const float *cursor = give_cursor(scene, v3d); copy_v3_v3(cursor_local, cursor); mul_m3_v3(imat, cursor_local); /* cursor */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) { float cursor_rel[3]; sub_v3_v3v3(cursor_rel, cursor_local, ebone->head); if (axis_flip) negate_v3(cursor_rel); ebone->roll = ED_rollBoneToVector(ebone, cursor_rel, axis_only); } } } else { float vec[3] = {0.0f, 0.0f, 0.0f}; if (type == CALC_ROLL_VIEW) { /* View */ RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d == NULL) { BKE_report(op->reports, RPT_ERROR, "No region view3d available"); return OPERATOR_CANCELLED; } copy_v3_v3(vec, rv3d->viewinv[2]); mul_m3_v3(imat, vec); } else if (type == CALC_ROLL_ACTIVE) { float mat[3][3], nor[3]; ebone = (EditBone *)arm->act_edbone; if (ebone == NULL) { BKE_report(op->reports, RPT_ERROR, "No active bone set"); return OPERATOR_CANCELLED; } sub_v3_v3v3(nor, ebone->tail, ebone->head); vec_roll_to_mat3(nor, ebone->roll, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ assert(type >= 0 && type <= 5); if (type < 3) vec[type] = 1.0f; else vec[type - 2] = -1.0f; mul_m3_v3(imat, vec); } if (axis_flip) negate_v3(vec); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) { /* roll func is a callback which assumes that all is well */ ebone->roll = ED_rollBoneToVector(ebone, vec, axis_only); } } } if (arm->flag & ARM_MIRROR_EDIT) { for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) { EditBone *ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, ebone); if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) { ebone->roll = -ebone_mirr->roll; } } } } /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); return OPERATOR_FINISHED; }
static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C) { RegionView3D *rv3d = CTX_wm_region_view3d(C); View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); Render *re; rctf viewplane; rcti disprect; float clipsta, clipend; bool orth; int job_update_flag = 0; char name[32]; /* ensure render engine exists */ re = engine->re; if (!re) { sprintf(name, "View3dPreview %p", (void *)ar); re = engine->re = RE_GetRender(name); if (!re) re = engine->re = RE_NewRender(name); engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; } /* check update_flag */ if (engine->update_flag & RE_ENGINE_UPDATE_MA) job_update_flag |= PR_UPDATE_MATERIAL; if (engine->update_flag & RE_ENGINE_UPDATE_OTHER) job_update_flag |= PR_UPDATE_MATERIAL; if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) { job_update_flag |= PR_UPDATE_DATABASE; /* load editmesh */ if (scene->obedit) ED_object_editmode_load(scene->obedit); } engine->update_flag = 0; /* check if viewport changed */ if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) { engine->last_winx = ar->winx; engine->last_winy = ar->winy; job_update_flag |= PR_UPDATE_RENDERSIZE; } if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) { copy_m4_m4(engine->last_viewmat, rv3d->viewmat); job_update_flag |= PR_UPDATE_VIEW; } render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth); if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) { engine->last_viewplane = viewplane; job_update_flag |= PR_UPDATE_VIEW; } render_view3d_disprect(scene, ar, v3d, rv3d, &disprect); if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) { engine->last_disprect = disprect; job_update_flag |= PR_UPDATE_RENDERSIZE; } /* any changes? go ahead and rerender */ if (job_update_flag) { engine->job_update_flag |= job_update_flag; return true; } return false; }