OpenGL: replace gluProject and gluUnProject, and simplify surrounding code.
Part of T49042.
This commit is contained in:
@@ -92,25 +92,17 @@ static float depth_read_zbuf(const ViewContext *vc, int x, int y)
|
||||
}
|
||||
|
||||
static bool depth_unproject(
|
||||
const ARegion *ar, const bglMats *mats,
|
||||
const ARegion *ar,
|
||||
const int mval[2], const double depth,
|
||||
float r_location_world[3])
|
||||
{
|
||||
double p[3];
|
||||
if (gluUnProject(
|
||||
(double)ar->winrct.xmin + mval[0] + 0.5,
|
||||
(double)ar->winrct.ymin + mval[1] + 0.5,
|
||||
depth, mats->modelview, mats->projection, (const GLint *)mats->viewport,
|
||||
&p[0], &p[1], &p[2]))
|
||||
{
|
||||
copy_v3fl_v3db(r_location_world, p);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
float centx = (float)mval[0] + 0.5f;
|
||||
float centy = (float)mval[1] + 0.5f;
|
||||
return ED_view3d_unproject(ar, centx, centy, depth, r_location_world);
|
||||
}
|
||||
|
||||
static bool depth_read_normal(
|
||||
const ViewContext *vc, const bglMats *mats, const int mval[2],
|
||||
const ViewContext *vc, const int mval[2],
|
||||
float r_normal[3])
|
||||
{
|
||||
/* pixels surrounding */
|
||||
@@ -126,7 +118,7 @@ static bool depth_read_normal(
|
||||
|
||||
const double depth = (double)depth_read_zbuf(vc, mval_ofs[0], mval_ofs[1]);
|
||||
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
|
||||
if (depth_unproject(ar, mats, mval_ofs, depth, coords[i])) {
|
||||
if (depth_unproject(ar, mval_ofs, depth, coords[i])) {
|
||||
depths_valid[i] = true;
|
||||
}
|
||||
}
|
||||
@@ -228,7 +220,6 @@ struct CurveDrawData {
|
||||
} prev;
|
||||
|
||||
ViewContext vc;
|
||||
bglMats mats;
|
||||
enum {
|
||||
CURVE_DRAW_IDLE = 0,
|
||||
CURVE_DRAW_PAINTING = 1,
|
||||
@@ -314,7 +305,7 @@ static bool stroke_elem_project(
|
||||
{
|
||||
const double depth = (double)depth_read_zbuf(&cdd->vc, mval_i[0], mval_i[1]);
|
||||
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
|
||||
if (depth_unproject(ar, &cdd->mats, mval_i, depth, r_location_world)) {
|
||||
if (depth_unproject(ar, mval_i, depth, r_location_world)) {
|
||||
is_location_world_set = true;
|
||||
if (r_normal_world) {
|
||||
zero_v3(r_normal_world);
|
||||
@@ -323,7 +314,7 @@ static bool stroke_elem_project(
|
||||
if (surface_offset != 0.0f) {
|
||||
const float offset = cdd->project.use_surface_offset_absolute ? 1.0f : radius;
|
||||
float normal[3];
|
||||
if (depth_read_normal(&cdd->vc, &cdd->mats, mval_i, normal)) {
|
||||
if (depth_read_normal(&cdd->vc, mval_i, normal)) {
|
||||
madd_v3_v3fl(r_location_world, normal, offset * surface_offset);
|
||||
if (r_normal_world) {
|
||||
copy_v3_v3(r_normal_world, normal);
|
||||
@@ -651,7 +642,7 @@ static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event)
|
||||
CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW,
|
||||
CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE))
|
||||
{
|
||||
if (depth_read_normal(&cdd->vc, &cdd->mats, event->mval, normal)) {
|
||||
if (depth_read_normal(&cdd->vc, event->mval, normal)) {
|
||||
if (cps->surface_plane == CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW) {
|
||||
float cross_a[3], cross_b[3];
|
||||
cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal);
|
||||
@@ -1187,8 +1178,6 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) &&
|
||||
(v3d->drawtype > OB_WIRE))
|
||||
{
|
||||
view3d_get_transformation(cdd->vc.ar, cdd->vc.rv3d, NULL, &cdd->mats);
|
||||
|
||||
/* needed or else the draw matrix can be incorrect */
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
|
||||
@@ -292,14 +292,6 @@ void setlinestyle(int nr);
|
||||
/* own working polygon offset */
|
||||
void bglPolygonOffset(float viewdist, float dist);
|
||||
|
||||
/* For caching opengl matrices (gluProject/gluUnProject) */
|
||||
typedef struct bglMats {
|
||||
double modelview[16];
|
||||
double projection[16];
|
||||
int viewport[4];
|
||||
} bglMats;
|
||||
void bgl_get_mats(bglMats *mats);
|
||||
|
||||
/* **** Color management helper functions for GLSL display/transform ***** */
|
||||
|
||||
/* Draw imbuf on a screen, preferably using GLSL display transform */
|
||||
|
||||
@@ -39,8 +39,7 @@ struct rcti;
|
||||
|
||||
/* sculpt.c */
|
||||
void ED_operatortypes_sculpt(void);
|
||||
void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *ar,
|
||||
struct RegionView3D *rv3d, struct Object *ob);
|
||||
void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *ar, struct Object *ob);
|
||||
int ED_sculpt_mask_box_select(struct bContext *C, struct ViewContext *vc, const struct rcti *rect, bool select, bool extend);
|
||||
|
||||
#endif /* __ED_SCULPT_H__ */
|
||||
|
||||
@@ -56,7 +56,6 @@ struct ViewContext;
|
||||
struct bContext;
|
||||
struct bPoseChannel;
|
||||
struct bScreen;
|
||||
struct bglMats;
|
||||
struct rctf;
|
||||
struct rcti;
|
||||
struct wmOperator;
|
||||
@@ -233,7 +232,9 @@ bool ED_view3d_win_to_segment(const struct ARegion *ar, struct View3D *v3d, cons
|
||||
float r_ray_start[3], float r_ray_end[3], const bool do_clip);
|
||||
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
|
||||
void ED_view3d_ob_project_mat_get_from_obmat(const struct RegionView3D *rv3d, float obmat[4][4], float pmat[4][4]);
|
||||
void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z);
|
||||
|
||||
void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3]);
|
||||
bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3]);
|
||||
|
||||
/* end */
|
||||
|
||||
@@ -262,7 +263,8 @@ bool ED_view3d_calc_render_border(struct Scene *scene, struct View3D *v3d,
|
||||
struct ARegion *ar, struct rcti *rect);
|
||||
|
||||
void ED_view3d_clipping_calc_from_boundbox(float clip[6][4], const struct BoundBox *clipbb, const bool is_flip);
|
||||
void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect);
|
||||
void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4],
|
||||
const struct ARegion *ar, const struct Object *ob, const struct rcti *rect);
|
||||
void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
|
||||
bool ED_view3d_clipping_test(const struct RegionView3D *rv3d, const float co[3], const bool is_local);
|
||||
void ED_view3d_clipping_set(struct RegionView3D *rv3d);
|
||||
@@ -312,7 +314,6 @@ void view3d_set_viewcontext(struct bContext *C, struct ViewContext *vc);
|
||||
void view3d_operator_needs_opengl(const struct bContext *C);
|
||||
void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar);
|
||||
void view3d_opengl_read_pixels(struct ARegion *ar, int x, int y, int w, int h, int format, int type, void *data);
|
||||
void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats);
|
||||
|
||||
/* XXX should move to BLI_math */
|
||||
bool edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]);
|
||||
|
||||
@@ -1418,7 +1418,7 @@ static bool bm_ray_cast_cb_elem_not_in_face_check(BMFace *f, void *user_data)
|
||||
* intersecting faces matching this face (or connected when an vert/edge) will be ignored.
|
||||
*/
|
||||
static bool point_is_visible(
|
||||
KnifeTool_OpData *kcd, const float p[3], const float s[2], bglMats *mats,
|
||||
KnifeTool_OpData *kcd, const float p[3], const float s[2],
|
||||
BMElem *ele_test)
|
||||
{
|
||||
BMFace *f_hit;
|
||||
@@ -1436,7 +1436,7 @@ static bool point_is_visible(
|
||||
float view[3], p_ofs[3];
|
||||
|
||||
/* TODO: I think there's a simpler way to get the required raycast ray */
|
||||
ED_view3d_unproject(mats, view, s[0], s[1], 0.0f);
|
||||
ED_view3d_unproject(kcd->vc.ar, s[0], s[1], 0.0f, view);
|
||||
|
||||
mul_m4_v3(kcd->ob->imat, view);
|
||||
|
||||
@@ -1509,7 +1509,6 @@ static void set_linehit_depth(KnifeTool_OpData *kcd, KnifeLineHit *lh)
|
||||
/* Finds visible (or all, if cutting through) edges that intersects the current screen drag line */
|
||||
static void knife_find_line_hits(KnifeTool_OpData *kcd)
|
||||
{
|
||||
bglMats mats;
|
||||
SmallHash faces, kfes, kfvs;
|
||||
float v1[3], v2[3], v3[3], v4[3], s1[2], s2[2];
|
||||
BVHTree *planetree, *tree;
|
||||
@@ -1539,8 +1538,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
|
||||
const bool use_hit_prev = true;
|
||||
const bool use_hit_curr = (kcd->is_drag_hold == false);
|
||||
|
||||
bgl_get_mats(&mats);
|
||||
|
||||
if (kcd->linehits) {
|
||||
MEM_freeN(kcd->linehits);
|
||||
kcd->linehits = NULL;
|
||||
@@ -1669,7 +1666,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
|
||||
knife_project_v2(kcd, v->cageco, s);
|
||||
d = dist_squared_to_line_segment_v2(s, s1, s2);
|
||||
if ((d <= vert_tol_sq) &&
|
||||
(point_is_visible(kcd, v->cageco, s, &mats, bm_elem_from_knife_vert(v, &kfe_hit))))
|
||||
(point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit))))
|
||||
{
|
||||
memset(&hit, 0, sizeof(hit));
|
||||
hit.v = v;
|
||||
@@ -1732,7 +1729,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
|
||||
* Need to find 3d intersection of ray through sint */
|
||||
knife_input_ray_segment(kcd, sint, 1.0f, r1, r2);
|
||||
isect_kind = isect_line_line_v3(kfe->v1->cageco, kfe->v2->cageco, r1, r2, p_cage, p_cage_tmp);
|
||||
if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, &mats, bm_elem_from_knife_edge(kfe))) {
|
||||
if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, bm_elem_from_knife_edge(kfe))) {
|
||||
memset(&hit, 0, sizeof(hit));
|
||||
if (kcd->snap_midpoints) {
|
||||
/* choose intermediate point snap too */
|
||||
@@ -1761,7 +1758,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
|
||||
float p[3], p_cage[3];
|
||||
|
||||
if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
|
||||
if (point_is_visible(kcd, p_cage, s1, &mats, (BMElem *)f)) {
|
||||
if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
|
||||
memset(&hit, 0, sizeof(hit));
|
||||
hit.f = f;
|
||||
copy_v3_v3(hit.hit, p);
|
||||
@@ -1773,7 +1770,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
|
||||
}
|
||||
|
||||
if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
|
||||
if (point_is_visible(kcd, p_cage, s2, &mats, (BMElem *)f)) {
|
||||
if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
|
||||
memset(&hit, 0, sizeof(hit));
|
||||
hit.f = f;
|
||||
copy_v3_v3(hit.hit, p);
|
||||
@@ -1806,13 +1803,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
|
||||
static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
|
||||
float r_origin[3], float r_origin_ofs[3])
|
||||
{
|
||||
bglMats mats;
|
||||
|
||||
bgl_get_mats(&mats);
|
||||
|
||||
/* unproject to find view ray */
|
||||
ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
|
||||
ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs);
|
||||
ED_view3d_unproject(kcd->vc.ar, mval[0], mval[1], 0.0f, r_origin);
|
||||
ED_view3d_unproject(kcd->vc.ar, mval[0], mval[1], ofs, r_origin_ofs);
|
||||
|
||||
/* transform into object space */
|
||||
invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
|
||||
@@ -3014,7 +3007,6 @@ static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
|
||||
void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through)
|
||||
{
|
||||
KnifeTool_OpData *kcd;
|
||||
bglMats mats;
|
||||
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
@@ -3033,10 +3025,6 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
|
||||
if (use_tag) {
|
||||
BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
|
||||
}
|
||||
|
||||
if (kcd->cut_through == false) {
|
||||
bgl_get_mats(&mats);
|
||||
}
|
||||
}
|
||||
|
||||
/* execute */
|
||||
@@ -3145,7 +3133,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
|
||||
float cent[3], cent_ss[2];
|
||||
BM_face_calc_point_in_face(f, cent);
|
||||
knife_project_v2(kcd, cent, cent_ss);
|
||||
if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats, (BMElem *)f)) &&
|
||||
if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, (BMElem *)f)) &&
|
||||
edbm_mesh_knife_point_isect(polys, cent_ss))
|
||||
{
|
||||
BM_elem_flag_enable(f, BM_ELEM_TAG);
|
||||
|
||||
@@ -353,7 +353,6 @@ static int pe_x_mirror(Object *ob)
|
||||
|
||||
typedef struct PEData {
|
||||
ViewContext vc;
|
||||
bglMats mats;
|
||||
|
||||
Scene *scene;
|
||||
Object *ob;
|
||||
@@ -399,8 +398,6 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
|
||||
PE_set_data(C, data);
|
||||
|
||||
view3d_set_viewcontext(C, &data->vc);
|
||||
/* note, the object argument means the modelview matrix does not account for the objects matrix, use viewmat rather than (obmat * viewmat) */
|
||||
view3d_get_transformation(data->vc.ar, data->vc.rv3d, NULL, &data->mats);
|
||||
|
||||
if (V3D_IS_ZBUF(data->vc.v3d)) {
|
||||
if (data->vc.v3d->flag & V3D_INVALID_BACKBUF) {
|
||||
@@ -441,7 +438,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
|
||||
{
|
||||
View3D *v3d= data->vc.v3d;
|
||||
ViewDepths *vd = data->vc.rv3d->depths;
|
||||
double ux, uy, uz;
|
||||
float depth;
|
||||
|
||||
/* nothing to do */
|
||||
@@ -457,9 +453,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
|
||||
}
|
||||
#endif
|
||||
|
||||
gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection,
|
||||
(GLint *)data->mats.viewport, &ux, &uy, &uz);
|
||||
|
||||
/* check if screen_co is within bounds because brush_cut uses out of screen coords */
|
||||
if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) {
|
||||
BLI_assert(vd && vd->depths);
|
||||
@@ -469,7 +462,10 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
|
||||
else
|
||||
return 0;
|
||||
|
||||
if ((float)uz - 0.00001f > depth)
|
||||
float win[3];
|
||||
ED_view3d_project(data->vc.ar, co, win);
|
||||
|
||||
if (win[2] - 0.00001f > depth)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
|
||||
@@ -969,33 +969,6 @@ void glaEnd2DDraw(gla2DDrawInfo *di)
|
||||
#endif /* UNUSED */
|
||||
|
||||
|
||||
/* Uses current OpenGL state to get view matrices for gluProject/gluUnProject */
|
||||
void bgl_get_mats(bglMats *mats)
|
||||
{
|
||||
const double badvalue = 1.0e-6;
|
||||
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, mats->modelview);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, mats->projection);
|
||||
glGetIntegerv(GL_VIEWPORT, (GLint *)mats->viewport);
|
||||
|
||||
/* Very strange code here - it seems that certain bad values in the
|
||||
* modelview matrix can cause gluUnProject to give bad results. */
|
||||
if (mats->modelview[0] < badvalue &&
|
||||
mats->modelview[0] > -badvalue)
|
||||
{
|
||||
mats->modelview[0] = 0;
|
||||
}
|
||||
if (mats->modelview[5] < badvalue &&
|
||||
mats->modelview[5] > -badvalue)
|
||||
{
|
||||
mats->modelview[5] = 0;
|
||||
}
|
||||
|
||||
/* Set up viewport so that gluUnProject will give correct values */
|
||||
mats->viewport[0] = 0;
|
||||
mats->viewport[1] = 0;
|
||||
}
|
||||
|
||||
/* *************** glPolygonOffset hack ************* */
|
||||
|
||||
/**
|
||||
|
||||
@@ -323,12 +323,10 @@ static void clip_planes_from_rect(bContext *C,
|
||||
{
|
||||
ViewContext vc;
|
||||
BoundBox bb;
|
||||
bglMats mats = {{0}};
|
||||
|
||||
view3d_operator_needs_opengl(C);
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats);
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect);
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, rect);
|
||||
negate_m4(clip_planes);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,7 +209,6 @@ bool paint_convert_bb_to_rect(struct rcti *rect,
|
||||
* 2D screens-space bounding box into four 3D planes) */
|
||||
void paint_calc_redraw_planes(float planes[4][4],
|
||||
const struct ARegion *ar,
|
||||
struct RegionView3D *rv3d,
|
||||
struct Object *ob,
|
||||
const struct rcti *screen_rect);
|
||||
|
||||
|
||||
@@ -251,7 +251,6 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
|
||||
{
|
||||
Sculpt *sd = vc->scene->toolsettings->sculpt;
|
||||
BoundBox bb;
|
||||
bglMats mats = {{0}};
|
||||
float clip_planes[4][4];
|
||||
float clip_planes_final[4][4];
|
||||
ARegion *ar = vc->ar;
|
||||
@@ -269,8 +268,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
|
||||
value = select ? 1.0 : 0.0;
|
||||
|
||||
/* transform the clip planes in object space */
|
||||
view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, &mats);
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect);
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, vc->ar, vc->obact, rect);
|
||||
negate_m4(clip_planes);
|
||||
|
||||
BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
|
||||
@@ -411,7 +409,6 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
|
||||
if (mcords) {
|
||||
float clip_planes[4][4], clip_planes_final[4][4];
|
||||
BoundBox bb;
|
||||
bglMats mats = {{0}};
|
||||
Object *ob;
|
||||
ViewContext vc;
|
||||
LassoMaskData data;
|
||||
@@ -429,7 +426,6 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
|
||||
* calculations done. Bounding box PBVH collision is not computed against enclosing rectangle
|
||||
* of lasso */
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats);
|
||||
|
||||
/* lasso data calculations */
|
||||
data.vc = &vc;
|
||||
@@ -445,7 +441,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
|
||||
mcords, mcords_tot,
|
||||
mask_lasso_px_cb, &data);
|
||||
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, &mats, &data.rect);
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, &data.rect);
|
||||
negate_m4(clip_planes);
|
||||
|
||||
BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
|
||||
|
||||
@@ -130,17 +130,12 @@ bool paint_convert_bb_to_rect(rcti *rect,
|
||||
* 2D screens-space bounding box into four 3D planes) */
|
||||
void paint_calc_redraw_planes(float planes[4][4],
|
||||
const ARegion *ar,
|
||||
RegionView3D *rv3d,
|
||||
Object *ob,
|
||||
const rcti *screen_rect)
|
||||
{
|
||||
BoundBox bb;
|
||||
bglMats mats;
|
||||
rcti rect;
|
||||
|
||||
memset(&bb, 0, sizeof(BoundBox));
|
||||
view3d_get_transformation(ar, rv3d, ob, &mats);
|
||||
|
||||
/* use some extra space just in case */
|
||||
rect = *screen_rect;
|
||||
rect.xmin -= 2;
|
||||
@@ -148,7 +143,7 @@ void paint_calc_redraw_planes(float planes[4][4],
|
||||
rect.ymin -= 2;
|
||||
rect.ymax += 2;
|
||||
|
||||
ED_view3d_clipping_calc(&bb, planes, &mats, &rect);
|
||||
ED_view3d_clipping_calc(&bb, planes, ar, ob, &rect);
|
||||
negate_m4(planes);
|
||||
}
|
||||
|
||||
|
||||
@@ -626,8 +626,7 @@ static bool sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar,
|
||||
RegionView3D *rv3d, Object *ob)
|
||||
void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar, Object *ob)
|
||||
{
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
/* copy here, original will be used below */
|
||||
@@ -635,7 +634,7 @@ void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar,
|
||||
|
||||
sculpt_extend_redraw_rect_previous(ob, &rect);
|
||||
|
||||
paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect);
|
||||
paint_calc_redraw_planes(planes, ar, ob, &rect);
|
||||
|
||||
/* we will draw this rect, so now we can set it as the previous partial rect.
|
||||
* Note that we don't update with the union of previous/current (rect), only with
|
||||
|
||||
@@ -941,14 +941,6 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
|
||||
if (tot) {
|
||||
int col_pack_prev = 0;
|
||||
|
||||
#if 0
|
||||
bglMats mats; /* ZBuffer depth vars */
|
||||
double ux, uy, uz;
|
||||
float depth;
|
||||
|
||||
if (v3d->zbuf)
|
||||
bgl_get_mats(&mats);
|
||||
#endif
|
||||
if (rv3d->rflag & RV3D_CLIPPING) {
|
||||
ED_view3d_clipping_disable();
|
||||
}
|
||||
@@ -3418,11 +3410,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
|
||||
|
||||
if (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_EDGEANG)) {
|
||||
BoundBox bb;
|
||||
bglMats mats = {{0}};
|
||||
const rcti rect = {0, ar->winx, 0, ar->winy};
|
||||
|
||||
view3d_get_transformation(ar, ar->regiondata, em->ob, &mats);
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, &mats, &rect);
|
||||
ED_view3d_clipping_calc(&bb, clip_planes, ar, em->ob, &rect);
|
||||
}
|
||||
|
||||
if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
|
||||
@@ -4276,7 +4266,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
|
||||
if (ob->sculpt->partial_redraw) {
|
||||
if (ar->do_draw & RGN_DRAW_PARTIAL) {
|
||||
ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
|
||||
ED_sculpt_redraw_planes_get(planes, ar, ob);
|
||||
fpl = planes;
|
||||
ob->sculpt->partial_redraw = 0;
|
||||
}
|
||||
@@ -4367,7 +4357,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
|
||||
if (ob->sculpt->partial_redraw) {
|
||||
if (ar->do_draw & RGN_DRAW_PARTIAL) {
|
||||
ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
|
||||
ED_sculpt_redraw_planes_get(planes, ar, ob);
|
||||
fpl = planes;
|
||||
ob->sculpt->partial_redraw = 0;
|
||||
}
|
||||
@@ -4753,7 +4743,7 @@ static void draw_mesh_fancy_new(Scene *scene, ARegion *ar, View3D *v3d, RegionVi
|
||||
|
||||
if (ob->sculpt->partial_redraw) {
|
||||
if (ar->do_draw & RGN_DRAW_PARTIAL) {
|
||||
ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
|
||||
ED_sculpt_redraw_planes_get(planes, ar, ob);
|
||||
fpl = planes;
|
||||
ob->sculpt->partial_redraw = 0;
|
||||
}
|
||||
@@ -4841,7 +4831,7 @@ static void draw_mesh_fancy_new(Scene *scene, ARegion *ar, View3D *v3d, RegionVi
|
||||
|
||||
if (ob->sculpt->partial_redraw) {
|
||||
if (ar->do_draw & RGN_DRAW_PARTIAL) {
|
||||
ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
|
||||
ED_sculpt_redraw_planes_get(planes, ar, ob);
|
||||
fpl = planes;
|
||||
ob->sculpt->partial_redraw = 0;
|
||||
}
|
||||
|
||||
@@ -3553,9 +3553,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
|
||||
float new_ofs[3];
|
||||
|
||||
/* ZBuffer depth vars */
|
||||
bglMats mats;
|
||||
float depth_close = FLT_MAX;
|
||||
double cent[2], p[3];
|
||||
float p[3];
|
||||
|
||||
/* note; otherwise opengl won't work */
|
||||
view3d_operator_needs_opengl(C);
|
||||
@@ -3569,7 +3568,6 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
|
||||
ED_view3d_dist_range_get(v3d, dist_range);
|
||||
|
||||
/* Get Z Depths, needed for perspective, nice for ortho */
|
||||
bgl_get_mats(&mats);
|
||||
ED_view3d_draw_depth(scene, ar, v3d, true);
|
||||
|
||||
{
|
||||
@@ -3585,11 +3583,11 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
|
||||
MEM_SAFE_FREE(depth_temp.depths);
|
||||
}
|
||||
|
||||
cent[0] = (((double)rect.xmin) + ((double)rect.xmax)) / 2;
|
||||
cent[1] = (((double)rect.ymin) + ((double)rect.ymax)) / 2;
|
||||
float centx = (((float)rect.xmin) + ((float)rect.xmax)) / 2;
|
||||
float centy = (((float)rect.ymin) + ((float)rect.ymax)) / 2;
|
||||
|
||||
if (rv3d->is_persp) {
|
||||
double p_corner[3];
|
||||
float p_corner[3];
|
||||
|
||||
/* no depths to use, we cant do anything! */
|
||||
if (depth_close == FLT_MAX) {
|
||||
@@ -3597,23 +3595,14 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
/* convert border to 3d coordinates */
|
||||
if ((!gluUnProject(cent[0], cent[1], depth_close,
|
||||
mats.modelview, mats.projection, (GLint *)mats.viewport,
|
||||
&p[0], &p[1], &p[2])) ||
|
||||
(!gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close,
|
||||
mats.modelview, mats.projection, (GLint *)mats.viewport,
|
||||
&p_corner[0], &p_corner[1], &p_corner[2])))
|
||||
if ((!ED_view3d_unproject(ar, centx, centy, depth_close, p)) ||
|
||||
(!ED_view3d_unproject(ar, rect.xmin, rect.ymin, depth_close, p_corner)))
|
||||
{
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
dvec[0] = p[0] - p_corner[0];
|
||||
dvec[1] = p[1] - p_corner[1];
|
||||
dvec[2] = p[2] - p_corner[2];
|
||||
|
||||
new_ofs[0] = -p[0];
|
||||
new_ofs[1] = -p[1];
|
||||
new_ofs[2] = -p[2];
|
||||
sub_v3_v3v3(dvec, p, p_corner);
|
||||
negate_v3_v3(new_ofs, p);
|
||||
|
||||
new_dist = len_v3(dvec);
|
||||
|
||||
@@ -3628,13 +3617,9 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
|
||||
new_dist = rv3d->dist;
|
||||
|
||||
/* convert the drawn rectangle into 3d space */
|
||||
if (depth_close != FLT_MAX && gluUnProject(cent[0], cent[1], depth_close,
|
||||
mats.modelview, mats.projection, (GLint *)mats.viewport,
|
||||
&p[0], &p[1], &p[2]))
|
||||
if (depth_close != FLT_MAX && ED_view3d_unproject(ar, centx, centy, depth_close, p))
|
||||
{
|
||||
new_ofs[0] = -p[0];
|
||||
new_ofs[1] = -p[1];
|
||||
new_ofs[2] = -p[2];
|
||||
negate_v3_v3(new_ofs, p);
|
||||
}
|
||||
else {
|
||||
float mval_f[2];
|
||||
@@ -4599,9 +4584,8 @@ void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
|
||||
|
||||
static int view3d_clipping_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
ViewContext vc;
|
||||
bglMats mats;
|
||||
rcti rect;
|
||||
|
||||
WM_operator_properties_border_to_rcti(op, &rect);
|
||||
@@ -4609,12 +4593,8 @@ static int view3d_clipping_exec(bContext *C, wmOperator *op)
|
||||
rv3d->rflag |= RV3D_CLIPPING;
|
||||
rv3d->clipbb = MEM_callocN(sizeof(BoundBox), "clipbb");
|
||||
|
||||
/* note; otherwise opengl won't work */
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
view3d_get_transformation(vc.ar, vc.rv3d, NULL, &mats); /* NULL because we don't want it in object space */
|
||||
ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, &mats, &rect);
|
||||
/* NULL object because we don't want it in object space */
|
||||
ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, ar, NULL, &rect);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -4910,9 +4890,7 @@ bool ED_view3d_autodist(
|
||||
const int mval[2], float mouse_worldloc[3],
|
||||
const bool alphaoverride, const float fallback_depth_pt[3])
|
||||
{
|
||||
bglMats mats; /* ZBuffer depth vars */
|
||||
float depth_close;
|
||||
double cent[2], p[3];
|
||||
int margin_arr[] = {0, 2, 4};
|
||||
int i;
|
||||
bool depth_ok = false;
|
||||
@@ -4920,9 +4898,6 @@ bool ED_view3d_autodist(
|
||||
/* Get Z Depths, needed for perspective, nice for ortho */
|
||||
ED_view3d_draw_depth(scene, ar, v3d, alphaoverride);
|
||||
|
||||
/* call after in case settings have been modified since last drawing, see: T47089 */
|
||||
bgl_get_mats(&mats);
|
||||
|
||||
/* Attempt with low margin's first */
|
||||
i = 0;
|
||||
do {
|
||||
@@ -4931,15 +4906,11 @@ bool ED_view3d_autodist(
|
||||
} while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
|
||||
|
||||
if (depth_ok) {
|
||||
cent[0] = (double)mval[0] + 0.5;
|
||||
cent[1] = (double)mval[1] + 0.5;
|
||||
float centx = (float)mval[0] + 0.5f;
|
||||
float centy = (float)mval[1] + 0.5f;
|
||||
|
||||
if (gluUnProject(cent[0], cent[1], depth_close,
|
||||
mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
|
||||
if (ED_view3d_unproject(ar, centx, centy, depth_close, mouse_worldloc))
|
||||
{
|
||||
mouse_worldloc[0] = (float)p[0];
|
||||
mouse_worldloc[1] = (float)p[1];
|
||||
mouse_worldloc[2] = (float)p[2];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4970,9 +4941,7 @@ void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
|
||||
bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3],
|
||||
int margin, float *force_depth)
|
||||
{
|
||||
bglMats mats; /* ZBuffer depth vars, could cache? */
|
||||
float depth;
|
||||
double cent[2], p[3];
|
||||
|
||||
/* Get Z Depths, needed for perspective, nice for ortho */
|
||||
if (force_depth)
|
||||
@@ -4983,21 +4952,9 @@ bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_world
|
||||
if (depth == FLT_MAX)
|
||||
return false;
|
||||
|
||||
cent[0] = (double)mval[0] + 0.5;
|
||||
cent[1] = (double)mval[1] + 0.5;
|
||||
|
||||
bgl_get_mats(&mats);
|
||||
|
||||
if (!gluUnProject(cent[0], cent[1], depth,
|
||||
mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mouse_worldloc[0] = (float)p[0];
|
||||
mouse_worldloc[1] = (float)p[1];
|
||||
mouse_worldloc[2] = (float)p[2];
|
||||
return true;
|
||||
float centx = (float)mval[0] + 0.5f;
|
||||
float centy = (float)mval[1] + 0.5f;
|
||||
return ED_view3d_unproject(ar, centx, centy, depth, mouse_worldloc);
|
||||
}
|
||||
|
||||
bool ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth)
|
||||
|
||||
@@ -36,14 +36,13 @@
|
||||
|
||||
#include "BLI_sys_types.h" /* int64_t */
|
||||
|
||||
#include "BIF_gl.h" /* bglMats */
|
||||
#include "BIF_glutil.h" /* bglMats */
|
||||
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "GPU_matrix.h"
|
||||
|
||||
#include "ED_view3d.h" /* own include */
|
||||
|
||||
#define BL_NEAR_CLIP 0.001
|
||||
@@ -656,16 +655,22 @@ void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, float obm
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses window coordinates (x,y) and depth component z to find a point in
|
||||
* modelspace */
|
||||
void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z)
|
||||
* Convert between region relative coordinates (x,y) and depth component z and
|
||||
* a point in world space. */
|
||||
void ED_view3d_project(const struct ARegion *ar, const float world[3], float region[3])
|
||||
{
|
||||
double ux, uy, uz;
|
||||
// viewport is set up to make coordinates relative to the region, not window
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
int viewport[4] = {0, 0, ar->winx, ar->winy};
|
||||
|
||||
gluUnProject(x, y, z, mats->modelview, mats->projection,
|
||||
(GLint *)mats->viewport, &ux, &uy, &uz);
|
||||
|
||||
out[0] = ux;
|
||||
out[1] = uy;
|
||||
out[2] = uz;
|
||||
gpuProject(world, rv3d->viewmat, rv3d->winmat, viewport, region);
|
||||
}
|
||||
|
||||
bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3])
|
||||
{
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
int viewport[4] = {0, 0, ar->winx, ar->winy};
|
||||
float region[3] = {regionx, regiony, regionz};
|
||||
|
||||
return gpuUnProject(region, rv3d->viewmat, rv3d->winmat, viewport, world);
|
||||
}
|
||||
|
||||
@@ -119,34 +119,6 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc)
|
||||
vc->obedit = CTX_data_edit_object(C);
|
||||
}
|
||||
|
||||
/*
|
||||
* ob == NULL if you want global matrices
|
||||
* */
|
||||
void view3d_get_transformation(const ARegion *ar, RegionView3D *rv3d, Object *ob, bglMats *mats)
|
||||
{
|
||||
float cpy[4][4];
|
||||
int i, j;
|
||||
|
||||
if (ob) {
|
||||
mul_m4_m4m4(cpy, rv3d->viewmat, ob->obmat);
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(cpy, rv3d->viewmat);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
mats->projection[i * 4 + j] = rv3d->winmat[i][j];
|
||||
mats->modelview[i * 4 + j] = cpy[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
mats->viewport[0] = ar->winrct.xmin;
|
||||
mats->viewport[1] = ar->winrct.ymin;
|
||||
mats->viewport[2] = ar->winx;
|
||||
mats->viewport[3] = ar->winy;
|
||||
}
|
||||
|
||||
/* ********************** view3d_select: selection manipulations ********************* */
|
||||
|
||||
/* local prototypes */
|
||||
|
||||
@@ -725,40 +725,35 @@ void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb,
|
||||
}
|
||||
}
|
||||
|
||||
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, const rcti *rect)
|
||||
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], const ARegion *ar, const Object *ob, const rcti *rect)
|
||||
{
|
||||
float modelview[4][4];
|
||||
double xs, ys, p[3];
|
||||
int val, flip_sign, a;
|
||||
|
||||
/* near zero floating point values can give issues with gluUnProject
|
||||
* in side view on some implementations */
|
||||
if (fabs(mats->modelview[0]) < 1e-6) mats->modelview[0] = 0.0;
|
||||
if (fabs(mats->modelview[5]) < 1e-6) mats->modelview[5] = 0.0;
|
||||
|
||||
/* Set up viewport so that gluUnProject will give correct values */
|
||||
mats->viewport[0] = 0;
|
||||
mats->viewport[1] = 0;
|
||||
/* init in case unproject fails */
|
||||
memset(bb->vec, 0, sizeof(bb->vec));
|
||||
|
||||
/* four clipping planes and bounding volume */
|
||||
/* first do the bounding volume */
|
||||
for (val = 0; val < 4; val++) {
|
||||
xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
|
||||
ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
|
||||
for (int val = 0; val < 4; val++) {
|
||||
float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax;
|
||||
float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax;
|
||||
|
||||
gluUnProject(xs, ys, 0.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
|
||||
copy_v3fl_v3db(bb->vec[val], p);
|
||||
ED_view3d_unproject(ar, xs, ys, 0.0, bb->vec[val]);
|
||||
ED_view3d_unproject(ar, xs, ys, 1.0, bb->vec[4 + val]);
|
||||
}
|
||||
|
||||
gluUnProject(xs, ys, 1.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
|
||||
copy_v3fl_v3db(bb->vec[4 + val], p);
|
||||
/* optionally transform to object space */
|
||||
if (ob) {
|
||||
float imat[4][4];
|
||||
invert_m4_m4(imat, ob->obmat);
|
||||
|
||||
for (int val = 0; val < 8; val++) {
|
||||
mul_m4_v3(imat, bb->vec[val]);
|
||||
}
|
||||
}
|
||||
|
||||
/* verify if we have negative scale. doing the transform before cross
|
||||
* product flips the sign of the vector compared to doing cross product
|
||||
* before transform then, so we correct for that. */
|
||||
for (a = 0; a < 16; a++)
|
||||
((float *)modelview)[a] = mats->modelview[a];
|
||||
flip_sign = is_negative_m4(modelview);
|
||||
int flip_sign = (ob) ? is_negative_m4(ob->obmat) : false;
|
||||
|
||||
ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#ifndef _GPU_MATRIX_H_
|
||||
#define _GPU_MATRIX_H_
|
||||
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -32,8 +29,11 @@
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#ifndef _GPU_MATRIX_H_
|
||||
#define _GPU_MATRIX_H_
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
#include "GPU_glew.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -110,12 +110,10 @@ void gpuOrtho(float left, float right, float bottom, float top, float near, floa
|
||||
void gpuFrustum(float left, float right, float bottom, float top, float near, float far);
|
||||
void gpuPerspective(float fovy, float aspect, float near, float far);
|
||||
|
||||
/* pass vector through current transform (world --> screen) */
|
||||
void gpuProject(const float obj[3], const float model[4][4], const float proj[4][4], const GLint view[4], float win[3]);
|
||||
|
||||
/* pass vector through inverse transform (world <-- screen) */
|
||||
bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const GLint view[4], float obj[3]);
|
||||
/* 3D Projection between Window and World Space */
|
||||
|
||||
void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3]);
|
||||
bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3]);
|
||||
|
||||
/* 2D Projection Matrix */
|
||||
|
||||
|
||||
@@ -487,19 +487,23 @@ void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY,
|
||||
gpuTranslate3f(-eyeX, -eyeY, -eyeZ);
|
||||
}
|
||||
|
||||
void gpuProject(const float obj[3], const float model[4][4], const float proj[4][4], const GLint view[4], float win[3])
|
||||
void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3])
|
||||
{
|
||||
float v[4];
|
||||
|
||||
mul_v4_m4v3(v, model, obj);
|
||||
mul_v4_m4v3(v, model, world);
|
||||
mul_m4_v4(proj, v);
|
||||
|
||||
if (v[3] != 0.0f) {
|
||||
mul_v3_fl(v, 1.0f / v[3]);
|
||||
}
|
||||
|
||||
win[0] = view[0] + (view[2] * (v[0] + 1)) * 0.5f;
|
||||
win[1] = view[1] + (view[3] * (v[1] + 1)) * 0.5f;
|
||||
win[2] = (v[2] + 1) * 0.5f;
|
||||
}
|
||||
|
||||
bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const GLint view[4], float obj[3])
|
||||
bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3])
|
||||
{
|
||||
float pm[4][4];
|
||||
float in[4];
|
||||
@@ -508,6 +512,7 @@ bool gpuUnProject(const float win[3], const float model[4][4], const float proj[
|
||||
mul_m4_m4m4(pm, proj, model);
|
||||
|
||||
if (!invert_m4(pm)) {
|
||||
zero_v3(world);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -528,19 +533,12 @@ bool gpuUnProject(const float win[3], const float model[4][4], const float proj[
|
||||
mul_v4_m4v3(out, pm, in);
|
||||
|
||||
if (out[3] == 0.0f) {
|
||||
copy_v3_v3(world, out);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
out[0] /= out[3];
|
||||
out[1] /= out[3];
|
||||
out[2] /= out[3];
|
||||
|
||||
obj[0] = out[0];
|
||||
obj[1] = out[1];
|
||||
obj[2] = out[2];
|
||||
|
||||
return true;
|
||||
}
|
||||
mul_v3_v3fl(world, out, 1.0f / out[3]);
|
||||
return true;
|
||||
}
|
||||
|
||||
const float *gpuGetModelViewMatrix3D(float m[4][4])
|
||||
|
||||
Reference in New Issue
Block a user