Drawing code for space_view3d module.
It's still not cleaned, have to check on context usage still.
Also missing is editmodes, armatures, and probably more.

Known issue: splitting to 2nd window gives bad opengl lighting.
Picture for fun:
http://www.blender.org/bf/rt2.jpg

Current stat: brought back almost 10k lines! :)
This commit is contained in:
2008-12-19 12:14:58 +00:00
parent c752ec9fc4
commit d92b45d558
16 changed files with 8510 additions and 141 deletions

View File

@@ -0,0 +1,110 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BIF_RETOPO_H
#define BIF_RETOPO_H
#include "DNA_vec_types.h"
/* For bglMats */
#include "BIF_glutil.h"
struct EditVert;
struct Mesh;
struct View3D;
typedef struct RetopoViewData {
bglMats mats;
char queue_matrix_update;
} RetopoViewData;
typedef struct RetopoPaintPoint {
struct RetopoPaintPoint *next, *prev;
vec2s loc;
short index;
float co[3];
struct EditVert *eve;
} RetopoPaintPoint;
typedef struct RetopoPaintLine {
struct RetopoPaintLine *next, *prev;
ListBase points;
ListBase hitlist; /* RetopoPaintHit */
RetopoPaintPoint *cyclic;
} RetopoPaintLine;
typedef struct RetopoPaintSel {
struct RetopoPaintSel *next, *prev;
RetopoPaintLine *line;
char first;
} RetopoPaintSel;
typedef struct RetopoPaintData {
char in_drag;
short sloc[2];
ListBase lines;
ListBase intersections; /* RetopoPaintPoint */
short seldist;
RetopoPaintSel nearest;
struct View3D *paint_v3d;
} RetopoPaintData;
RetopoPaintData *get_retopo_paint_data(void);
char retopo_mesh_check(void);
char retopo_curve_check(void);
void retopo_end_okee(void);
void retopo_free_paint_data(RetopoPaintData *rpd);
void retopo_free_paint(void);
char retopo_mesh_paint_check(void);
void retopo_paint_view_update(struct View3D *v3d);
void retopo_force_update(void);
void retopo_paint_toggle(void*,void*);
char retopo_paint(const unsigned short event);
void retopo_draw_paint_lines(void);
RetopoPaintData *retopo_paint_data_copy(RetopoPaintData *rpd);
void retopo_toggle(void*,void*);
void retopo_do_vert(struct View3D *v3d, float *v);
void retopo_do_all(void);
void retopo_do_all_cb(void *, void *);
void retopo_queue_updates(struct View3D *v3d);
void retopo_matrix_update(struct View3D *v3d);
void retopo_free_view_data(struct View3D *v3d);
#endif

View File

@@ -31,8 +31,9 @@
/* **************** GENERAL EDITOR-WIDE TYPES AND DEFINES ************************** */
/* old blender defines... should be depricated? */
#define SELECT 1
#define ACTIVE 2
#define DESELECT 0
#define SELECT 1
#define ACTIVE 2
#endif /* ED_TYPES_H */

View File

@@ -48,6 +48,7 @@ CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
CPPFLAGS += -I../../gpu
CPPFLAGS += -I../../render/extern/include
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include

View File

@@ -6,5 +6,6 @@ sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include #/intern/guardedalloc #intern/bmfont'
incs += ' ../../gpu'
env.BlenderLib ( 'bf_editors_space_view3d', sources, Split(incs), [], libtype=['core','intern'], priority=[35, 40] )

View File

@@ -0,0 +1,579 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* Contributor(s): Blender Foundation, full update, glsl support
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <string.h>
#include <math.h>
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_edgehash.h"
#include "BLI_editVert.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "DNA_image_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "DNA_userdef_types.h"
#include "BKE_bmfont.h"
#include "BKE_context.h"
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_property.h"
#include "BKE_utildefines.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "UI_resources.h"
#include "UI_interface_icons.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
#include "view3d_intern.h" // own include
/***/
/* Flags for marked edges */
enum {
eEdge_Visible = (1<<0),
eEdge_Select = (1<<1),
};
/* Creates a hash of edges to flags indicating
* adjacent tface select/active/etc flags.
*/
static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
{
int *flags_p;
if (!BLI_edgehash_haskey(eh, v0, v1)) {
BLI_edgehash_insert(eh, v0, v1, 0);
}
flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
*flags_p |= flags;
}
static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
{
EdgeHash *eh = BLI_edgehash_new();
int i;
MFace *mf;
MTFace *tf = NULL;
for (i=0; i<me->totface; i++) {
mf = &me->mface[i];
if (me->mtface)
tf = &me->mtface[i];
if (mf->v3) {
if (!(mf->flag&ME_HIDE)) {
unsigned int flags = eEdge_Visible;
if (mf->flag&ME_FACE_SEL) flags |= eEdge_Select;
get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
if (mf->v4) {
get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
} else {
get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
}
}
}
}
return eh;
}
static int draw_tfaces3D__setHiddenOpts(void *userData, int index)
{
struct { Mesh *me; EdgeHash *eh; } *data = userData;
MEdge *med = &data->me->medge[index];
uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
if((G.f & G_DRAWSEAMS) && (med->flag&ME_SEAM)) {
return 0;
} else if(G.f & G_DRAWEDGES){
if (G.f&G_HIDDENEDGES) {
return 1;
} else {
return (flags & eEdge_Visible);
}
} else {
return (flags & eEdge_Select);
}
}
static int draw_tfaces3D__setSeamOpts(void *userData, int index)
{
struct { Mesh *me; EdgeHash *eh; } *data = userData;
MEdge *med = &data->me->medge[index];
uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
if (med->flag&ME_SEAM) {
if (G.f&G_HIDDENEDGES) {
return 1;
} else {
return (flags & eEdge_Visible);
}
} else {
return 0;
}
}
static int draw_tfaces3D__setSelectOpts(void *userData, int index)
{
struct { Mesh *me; EdgeHash *eh; } *data = userData;
MEdge *med = &data->me->medge[index];
uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
return flags & eEdge_Select;
}
static int draw_tfaces3D__setActiveOpts(void *userData, int index)
{
struct { Mesh *me; EdgeHash *eh; } *data = userData;
MEdge *med = &data->me->medge[index];
uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
if (flags & eEdge_Select) {
return 1;
} else {
return 0;
}
}
static int draw_tfaces3D__drawFaceOpts(void *userData, int index)
{
Mesh *me = (Mesh*)userData;
MFace *mface = &me->mface[index];
if (!(mface->flag&ME_HIDE) && (mface->flag&ME_FACE_SEL))
return 2; /* Don't set color */
else
return 0;
}
static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm)
{
struct { Mesh *me; EdgeHash *eh; } data;
data.me = me;
data.eh = get_tface_mesh_marked_edge_info(me);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
bglPolygonOffset(1.0);
/* Draw (Hidden) Edges */
UI_ThemeColor(TH_EDGE_FACESEL);
dm->drawMappedEdges(dm, draw_tfaces3D__setHiddenOpts, &data);
/* Draw Seams */
if(G.f & G_DRAWSEAMS) {
UI_ThemeColor(TH_EDGE_SEAM);
glLineWidth(2);
dm->drawMappedEdges(dm, draw_tfaces3D__setSeamOpts, &data);
glLineWidth(1);
}
/* Draw Selected Faces */
if(G.f & G_DRAWFACES) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
UI_ThemeColor4(TH_FACE_SELECT);
dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)me);
glDisable(GL_BLEND);
}
bglPolygonOffset(1.0);
/* Draw Stippled Outline for selected faces */
glColor3ub(255, 255, 255);
setlinestyle(1);
dm->drawMappedEdges(dm, draw_tfaces3D__setSelectOpts, &data);
setlinestyle(0);
dm->drawMappedEdges(dm, draw_tfaces3D__setActiveOpts, &data);
bglPolygonOffset(0.0); // resets correctly now, even after calling accumulated offsets
BLI_edgehash_free(data.eh, NULL);
}
static Material *give_current_material_or_def(Object *ob, int matnr)
{
extern Material defmaterial; // render module abuse...
Material *ma= give_current_material(ob, matnr);
return ma?ma:&defmaterial;
}
static int set_draw_settings_cached(int clearcache, int textured, MTFace *texface, int lit, Object *litob, int litmatnr, int doublesided)
{
static int c_textured;
static int c_lit;
static int c_doublesided;
static MTFace *c_texface;
static Object *c_litob;
static int c_litmatnr;
static int c_badtex;
if (clearcache) {
c_textured= c_lit= c_doublesided= -1;
c_texface= (MTFace*) -1;
c_litob= (Object*) -1;
c_litmatnr= -1;
c_badtex= 0;
}
if (texface) {
lit = lit && (lit==-1 || texface->mode&TF_LIGHT);
textured = textured && (texface->mode&TF_TEX);
doublesided = texface->mode&TF_TWOSIDE;
} else {
textured = 0;
}
if (doublesided!=c_doublesided) {
if (doublesided) glDisable(GL_CULL_FACE);
else glEnable(GL_CULL_FACE);
c_doublesided= doublesided;
}
if (textured!=c_textured || texface!=c_texface) {
if (textured ) {
c_badtex= !GPU_set_tpage(texface);
} else {
GPU_set_tpage(0);
c_badtex= 0;
}
c_textured= textured;
c_texface= texface;
}
if (c_badtex) lit= 0;
if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) {
if (lit) {
Material *ma= give_current_material_or_def(litob, litmatnr+1);
float spec[4];
spec[0]= ma->spec*ma->specr;
spec[1]= ma->spec*ma->specg;
spec[2]= ma->spec*ma->specb;
spec[3]= 1.0;
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
}
else {
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
}
c_lit= lit;
c_litob= litob;
c_litmatnr= litmatnr;
}
return c_badtex;
}
/* Icky globals, fix with userdata parameter */
struct TextureDrawState {
Object *ob;
int islit, istex;
unsigned char obcol[4];
} Gtexdraw = {NULL, 0, 0, {0, 0, 0, 0}};
static void draw_textured_begin(Scene *scene, View3D *v3d, Object *ob)
{
unsigned char obcol[4];
int istex, solidtex= 0;
if(v3d->drawtype==OB_SOLID || (ob==G.obedit && v3d->drawtype!=OB_TEXTURE)) {
/* draw with default lights in solid draw mode and edit mode */
solidtex= 1;
Gtexdraw.islit= -1;
}
else
/* draw with lights in the scene otherwise */
Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, v3d->viewmat);
obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
else istex= 0;
Gtexdraw.ob = ob;
Gtexdraw.istex = istex;
memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
set_draw_settings_cached(1, 0, 0, Gtexdraw.islit, 0, 0, 0);
glShadeModel(GL_SMOOTH);
}
static void draw_textured_end()
{
/* switch off textures */
GPU_set_tpage(0);
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
/* XXX, bad patch - GPU_default_lights() calls
* glLightfv(GL_LIGHT_POSITION, ...) which
* is transformed by the current matrix... we
* need to make sure that matrix is identity.
*
* It would be better if drawmesh.c kept track
* of and restored the light settings it changed.
* - zr
*/
glPushMatrix();
glLoadIdentity();
GPU_default_lights();
glPopMatrix();
}
static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
{
if (tface && (tface->mode&TF_INVISIBLE)) return 0;
if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
glColor3ub(0xFF, 0x00, 0xFF);
return 2; /* Don't set color */
} else if (tface && tface->mode&TF_OBCOL) {
glColor3ubv(Gtexdraw.obcol);
return 2; /* Don't set color */
} else if (!mcol) {
if (tface) glColor3f(1.0, 1.0, 1.0);
else {
Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
if(ma) glColor3f(ma->r, ma->g, ma->b);
else glColor3f(1.0, 1.0, 1.0);
}
return 2; /* Don't set color */
} else {
return 1; /* Set color from mcol */
}
}
static int draw_tface_mapped__set_draw(void *userData, int index)
{
Mesh *me = (Mesh*)userData;
MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
MFace *mface = (me->mface)? &me->mface[index]: NULL;
MCol *mcol = (me->mcol)? &me->mcol[index]: NULL;
int matnr = me->mface[index].mat_nr;
if (mface && mface->flag&ME_HIDE) return 0;
return draw_tface__set_draw(tface, mcol, matnr);
}
static int draw_em_tf_mapped__set_draw(void *userData, int index)
{
EditMesh *em = userData;
EditFace *efa= NULL; // XXX = EM_get_face_for_index(index);
MTFace *tface;
MCol *mcol;
int matnr;
if (efa==NULL || efa->h)
return 0;
tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
matnr = efa->mat_nr;
return draw_tface__set_draw(tface, mcol, matnr);
}
static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
{
Mesh *me = (Mesh*)userData;
MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
MFace *mface = (me->mface)? &me->mface[index]: NULL;
if ((mface->flag&ME_HIDE) || (tface && (tface->mode&TF_INVISIBLE)))
return 0;
*drawSmooth_r = 1;
return 1;
}
void draw_mesh_text(Object *ob, int glsl)
{
Mesh *me = ob->data;
DerivedMesh *ddm;
MFace *mf, *mface= me->mface;
MTFace *tface= me->mtface;
MCol *mcol= me->mcol; /* why does mcol exist? */
bProperty *prop = get_ob_property(ob, "Text");
GPUVertexAttribs gattribs;
int a, totface= me->totface;
/* don't draw without tfaces */
if(!tface)
return;
/* don't draw when editing */
if(ob==G.obedit)
return;
else if(ob==OBACT)
if(FACESEL_PAINT_TEST)
return;
ddm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
int mode= tface->mode;
int matnr= mf->mat_nr;
int mf_smooth= mf->flag & ME_SMOOTH;
if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) {
float v1[3], v2[3], v3[3], v4[3];
char string[MAX_PROPSTRING];
int characters, i, glattrib= -1, badtex= 0;
if(glsl) {
GPU_enable_material(matnr+1, &gattribs);
for(i=0; i<gattribs.totlayer; i++) {
if(gattribs.layer[i].type == CD_MTFACE) {
glattrib = gattribs.layer[i].glindex;
break;
}
}
}
else {
badtex = set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE);
if (badtex) {
if (mcol) mcol+=4;
continue;
}
}
ddm->getVertCo(ddm, mf->v1, v1);
ddm->getVertCo(ddm, mf->v2, v2);
ddm->getVertCo(ddm, mf->v3, v3);
if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
// The BM_FONT handling is in the gpu module, shared with the
// game engine, was duplicated previously
set_property_valstr(prop, string);
characters = strlen(string);
if(!BKE_image_get_ibuf(tface->tpage, NULL))
characters = 0;
if (!mf_smooth) {
float nor[3];
CalcNormFloat(v1, v2, v3, nor);
glNormal3fv(nor);
}
GPU_render_text(tface, tface->mode, string, characters,
(unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
}
if (mcol) {
mcol+=4;
}
}
ddm->release(ddm);
}
void draw_mesh_textured(Scene *scene, View3D *v3d, Object *ob, DerivedMesh *dm, int faceselect)
{
Mesh *me= ob->data;
/* correct for negative scale */
if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
else glFrontFace(GL_CCW);
/* draw the textured mesh */
draw_textured_begin(scene, v3d, ob);
if(ob==G.obedit) {
dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, G.editMesh);
} else if(faceselect) {
if(G.f & G_WEIGHTPAINT)
dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1);
else
dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me);
}
else
dm->drawFacesTex(dm, draw_tface__set_draw);
/* draw game engine text hack */
if(get_ob_property(ob, "Text"))
draw_mesh_text(ob, 0);
draw_textured_end();
/* draw edges and selected faces over textured mesh */
if(!G.obedit && faceselect)
draw_tfaces3D(ob, me, dm);
/* reset from negative scale correction */
glFrontFace(GL_CCW);
/* in editmode, the blend mode needs to be set incase it was ADD */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

File diff suppressed because it is too large Load Diff

View File

@@ -33,6 +33,7 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_group_types.h"
#include "DNA_key_types.h"
#include "DNA_object_types.h"
#include "DNA_space_types.h"
@@ -72,12 +73,16 @@
#include "ED_screen.h"
#include "ED_util.h"
#include "ED_types.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "UI_view2d.h"
#include "GPU_draw.h"
#include "GPU_material.h"
#include "view3d_intern.h" // own include
@@ -1145,6 +1150,178 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
// XXX areawinset(ar->win); // restore viewport / scissor
}
/* ****************** View3d afterdraw *************** */
typedef struct View3DAfter {
struct View3DAfter *next, *prev;
struct Base *base;
int type, flag;
} View3DAfter;
/* temp storage of Objects that need to be drawn as last */
void add_view3d_after(View3D *v3d, Base *base, int type, int flag)
{
View3DAfter *v3da= MEM_callocN(sizeof(View3DAfter), "View 3d after");
BLI_addtail(&v3d->afterdraw, v3da);
v3da->base= base;
v3da->type= type;
v3da->flag= flag;
}
/* clears zbuffer and draws it over */
static void view3d_draw_xray(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, int clear)
{
View3DAfter *v3da, *next;
int doit= 0;
for(v3da= v3d->afterdraw.first; v3da; v3da= v3da->next)
if(v3da->type==V3D_XRAY) doit= 1;
if(doit) {
if(clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT);
v3d->xray= TRUE;
for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
next= v3da->next;
if(v3da->type==V3D_XRAY) {
draw_object(C, scene, ar, v3d, v3da->base, v3da->flag);
BLI_remlink(&v3d->afterdraw, v3da);
MEM_freeN(v3da);
}
}
v3d->xray= FALSE;
}
}
/* disables write in zbuffer and draws it over */
static void view3d_draw_transp(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d)
{
View3DAfter *v3da, *next;
glDepthMask(0);
v3d->transp= TRUE;
for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
next= v3da->next;
if(v3da->type==V3D_TRANSP) {
draw_object(C, scene, ar, v3d, v3da->base, v3da->flag);
BLI_remlink(&v3d->afterdraw, v3da);
MEM_freeN(v3da);
}
}
v3d->transp= FALSE;
glDepthMask(1);
}
/* *********************** */
/*
In most cases call draw_dupli_objects,
draw_dupli_objects_color was added because when drawing set dupli's
we need to force the color
*/
static void draw_dupli_objects_color(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, Base *base, int color)
{
ListBase *lb;
DupliObject *dob;
Base tbase;
BoundBox *bb= NULL;
GLuint displist=0;
short transflag, use_displist= -1; /* -1 is initialize */
char dt, dtx;
if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
tbase.flag= OB_FROMDUPLI|base->flag;
lb= object_duplilist(scene, base->object);
for(dob= lb->first; dob; dob= dob->next) {
if(dob->no_draw);
else {
tbase.object= dob->ob;
/* extra service: draw the duplicator in drawtype of parent */
/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
dt= tbase.object->dt; tbase.object->dt= MIN2(tbase.object->dt, base->object->dt);
dtx= tbase.object->dtx; tbase.object->dtx= base->object->dtx;
/* negative scale flag has to propagate */
transflag= tbase.object->transflag;
if(base->object->transflag & OB_NEG_SCALE)
tbase.object->transflag ^= OB_NEG_SCALE;
UI_ThemeColorBlend(color, TH_BACK, 0.5);
/* generate displist, test for new object */
if(use_displist==1 && dob->prev && dob->prev->ob!=dob->ob) {
use_displist= -1;
glDeleteLists(displist, 1);
}
/* generate displist */
if(use_displist == -1) {
/* lamp drawing messes with matrices, could be handled smarter... but this works */
if(dob->ob->type==OB_LAMP || dob->type==OB_DUPLIGROUP)
use_displist= 0;
else {
/* disable boundbox check for list creation */
object_boundbox_flag(dob->ob, OB_BB_DISABLED, 1);
/* need this for next part of code */
bb= object_get_boundbox(dob->ob);
Mat4One(dob->ob->obmat); /* obmat gets restored */
displist= glGenLists(1);
glNewList(displist, GL_COMPILE);
draw_object(C, scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
glEndList();
use_displist= 1;
object_boundbox_flag(dob->ob, OB_BB_DISABLED, 0);
}
}
if(use_displist) {
wmMultMatrix(CTX_wm_window(C), dob->mat);
if(boundbox_clip(v3d, dob->mat, bb))
glCallList(displist);
wmLoadMatrix(CTX_wm_window(C), v3d->viewmat);
}
else {
Mat4CpyMat4(dob->ob->obmat, dob->mat);
draw_object(C, scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
}
tbase.object->dt= dt;
tbase.object->dtx= dtx;
tbase.object->transflag= transflag;
}
}
/* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
free_object_duplilist(lb); /* does restore */
if(use_displist)
glDeleteLists(displist, 1);
}
static void draw_dupli_objects(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, Base *base)
{
/* define the color here so draw_dupli_objects_color can be called
* from the set loop */
int color= (base->flag & SELECT)?TH_SELECT:TH_WIRE;
/* debug */
if(base->object->dup_group && base->object->dup_group->id.us<1)
color= TH_REDALERT;
draw_dupli_objects_color(C, scene, ar, v3d, base, color);
}
void view3d_update_depths(ARegion *ar, View3D *v3d)
{
/* Create storage for, and, if necessary, copy depth buffer */
@@ -1174,7 +1351,7 @@ void view3d_update_depths(ARegion *ar, View3D *v3d)
}
/* Enable sculpting in wireframe mode by drawing sculpt object only to the depth buffer */
static void draw_sculpt_depths(Scene *scene, View3D *v3d)
static void draw_sculpt_depths(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d)
{
Object *ob = OBACT;
@@ -1193,7 +1370,7 @@ static void draw_sculpt_depths(Scene *scene, View3D *v3d)
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_DEPTH_TEST);
// XXX draw_object(BASACT, 0);
draw_object(C, scene, ar, v3d, BASACT, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
if(!depth_on)
glDisable(GL_DEPTH_TEST);
@@ -1204,6 +1381,185 @@ static void draw_sculpt_depths(Scene *scene, View3D *v3d)
}
}
void draw_depth(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *))
{
Base *base;
Scene *sce;
short zbuf, flag;
float glalphaclip;
/* temp set drawtype to solid */
/* Setting these temporarily is not nice */
zbuf = v3d->zbuf;
flag = v3d->flag;
glalphaclip = U.glalphaclip;
U.glalphaclip = 0.5; /* not that nice but means we wont zoom into billboards */
v3d->flag &= ~V3D_SELECT_OUTLINE;
setwinmatrixview3d(CTX_wm_window(C), v3d, ar->winx, ar->winy, NULL); /* 0= no pick rect */
setviewmatrixview3d(v3d); /* note: calls where_is_object for camera... */
Mat4MulMat4(v3d->persmat, v3d->viewmat, v3d->winmat);
Mat4Invert(v3d->persinv, v3d->persmat);
Mat4Invert(v3d->viewinv, v3d->viewmat);
glClear(GL_DEPTH_BUFFER_BIT);
wmLoadMatrix(CTX_wm_window(C), v3d->viewmat);
// persp(PERSP_STORE); // store correct view for persp(PERSP_VIEW) calls
if(v3d->flag & V3D_CLIPPING) {
view3d_set_clipping(v3d);
}
v3d->zbuf= TRUE;
glEnable(GL_DEPTH_TEST);
/* draw set first */
if(scene->set) {
for(SETLOOPER(scene->set, base)) {
if(v3d->lay & base->lay) {
if (func == NULL || func(base)) {
draw_object(C, scene, ar, v3d, base, 0);
if(base->object->transflag & OB_DUPLI) {
draw_dupli_objects_color(C, scene, ar, v3d, base, TH_WIRE);
}
}
}
}
}
for(base= scene->base.first; base; base= base->next) {
if(v3d->lay & base->lay) {
if (func == NULL || func(base)) {
/* dupli drawing */
if(base->object->transflag & OB_DUPLI) {
draw_dupli_objects(C, scene, ar, v3d, base);
}
draw_object(C, scene, ar, v3d, base, 0);
}
}
}
/* this isnt that nice, draw xray objects as if they are normal */
if (v3d->afterdraw.first) {
View3DAfter *v3da, *next;
int num = 0;
v3d->xray= TRUE;
glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
next= v3da->next;
if(v3da->type==V3D_XRAY) {
draw_object(C, scene, ar, v3d, v3da->base, 0);
num++;
}
/* dont remove this time */
}
v3d->xray= FALSE;
glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
next= v3da->next;
if(v3da->type==V3D_XRAY) {
v3d->xray= TRUE; v3d->transp= FALSE;
} else if (v3da->type==V3D_TRANSP) {
v3d->xray= FALSE; v3d->transp= TRUE;
}
draw_object(C, scene, ar, v3d, v3da->base, 0); /* Draw Xray or Transp objects normally */
BLI_remlink(&v3d->afterdraw, v3da);
MEM_freeN(v3da);
}
v3d->xray= FALSE;
v3d->transp= FALSE;
}
v3d->zbuf = zbuf;
U.glalphaclip = glalphaclip;
v3d->flag = flag;
}
typedef struct View3DShadow {
struct View3DShadow *next, *prev;
GPULamp *lamp;
} View3DShadow;
static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par, float obmat[][4], ListBase *shadows)
{
GPULamp *lamp;
View3DShadow *shadow;
lamp = GPU_lamp_from_blender(scene, ob, par);
if(lamp) {
GPU_lamp_update(lamp, ob->lay, obmat);
if((ob->lay & v3d->lay) && GPU_lamp_has_shadow_buffer(lamp)) {
shadow= MEM_callocN(sizeof(View3DShadow), "View3DShadow");
shadow->lamp = lamp;
BLI_addtail(shadows, shadow);
}
}
}
static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
{
ListBase shadows;
View3DShadow *shadow;
Scene *sce;
Base *base;
Object *ob;
shadows.first= shadows.last= NULL;
/* update lamp transform and gather shadow lamps */
for(SETLOOPER(scene, base)) {
ob= base->object;
if(ob->type == OB_LAMP)
gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, &shadows);
if (ob->transflag & OB_DUPLI) {
DupliObject *dob;
ListBase *lb = object_duplilist(scene, ob);
for(dob=lb->first; dob; dob=dob->next)
if(dob->ob->type==OB_LAMP)
gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, &shadows);
free_object_duplilist(lb);
}
}
/* render shadows after updating all lamps, nested object_duplilist
* don't work correct since it's replacing object matrices */
for(shadow=shadows.first; shadow; shadow=shadow->next) {
/* this needs to be done better .. */
float viewmat[4][4], winmat[4][4];
int drawtype, lay, winsize, flag2;
drawtype= v3d->drawtype;
lay= v3d->lay;
flag2= v3d->flag2 & V3D_SOLID_TEX;
v3d->drawtype = OB_SOLID;
v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
v3d->flag2 &= ~V3D_SOLID_TEX;
GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
// XXX drawview3d_render(v3d, viewmat, winsize, winsize, winmat, 1);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype= drawtype;
v3d->lay= lay;
v3d->flag2 |= flag2;
}
BLI_freelistN(&shadows);
}
void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
{
@@ -1228,8 +1584,8 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
}
/* shadow buffers, before we setup matrices */
// if(draw_glsl_material(NULL, v3d->drawtype))
// gpu_update_lamps_shadows(scene, v3d);
if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
gpu_update_lamps_shadows(scene, v3d);
setwinmatrixview3d(CTX_wm_window(C), v3d, ar->winx, ar->winy, NULL); /* 0= no pick rect */
setviewmatrixview3d(v3d); /* note: calls where_is_object for camera... */
@@ -1319,10 +1675,10 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
if(v3d->lay & base->lay) {
UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
// XXX draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET);
draw_object(C, scene, ar, v3d, base, DRAW_CONSTCOLOR|DRAW_SCENESET);
if(base->object->transflag & OB_DUPLI) {
// XXX draw_dupli_objects_color(v3d, base, TH_WIRE);
draw_dupli_objects_color(C, scene, ar, v3d, base, TH_WIRE);
}
}
}
@@ -1336,10 +1692,11 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
/* dupli drawing */
if(base->object->transflag & OB_DUPLI) {
// XXX draw_dupli_objects(v3d, base);
draw_dupli_objects(C, scene, ar, v3d, base);
}
if((base->flag & SELECT)==0) {
// XXX if(base->object!=G.obedit) draw_object(base, 0);
if(base->object!=G.obedit)
draw_object(C, scene, ar, v3d, base, 0);
}
}
}
@@ -1352,14 +1709,14 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
/* draw selected and editmode */
for(base= scene->base.first; base; base= base->next) {
if(v3d->lay & base->lay) {
// if (base->object==G.obedit || ( base->flag & SELECT) )
// XXX draw_object(base, 0);
if (base->object==G.obedit || ( base->flag & SELECT) )
draw_object(C, scene, ar, v3d, base, 0);
}
}
if(!retopo && sculptparticle && !(obact && (obact->dtx & OB_DRAWXRAY))) {
if(G.f & G_SCULPTMODE)
draw_sculpt_depths(scene, v3d);
draw_sculpt_depths(C, scene, ar, v3d);
view3d_update_depths(ar, v3d);
}
@@ -1375,12 +1732,12 @@ void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d)
// if(scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID);
/* Transp and X-ray afterdraw stuff */
// view3d_draw_transp(v3d);
// view3d_draw_xray(v3d, 1); // clears zbuffer if it is used!
view3d_draw_transp(C, scene, ar, v3d);
view3d_draw_xray(C, scene, ar, v3d, 1); // clears zbuffer if it is used!
if(!retopo && sculptparticle && (obact && (OBACT->dtx & OB_DRAWXRAY))) {
if(G.f & G_SCULPTMODE)
draw_sculpt_depths(scene, v3d);
draw_sculpt_depths(C, scene, ar, v3d);
view3d_update_depths(ar, v3d);
}

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@
#include <string.h>
#include <stdio.h>
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"

View File

@@ -30,6 +30,11 @@
/* internal exports only */
struct wmWindow;
struct BoundBox;
struct Object;
struct DerivedMesh;
typedef struct ViewDepths {
unsigned short w, h;
float *depths;
@@ -43,34 +48,75 @@ typedef struct ViewDepths {
#define DRAW_CONSTCOLOR 2
#define DRAW_SCENESET 4
#define V3D_XRAY 1
#define V3D_TRANSP 2
/* project short */
#define IS_CLIPPED 12000
/* view3d_header.c */
void view3d_header_buttons(const bContext *C, ARegion *ar);
/* drawobject.c */
void draw_object(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag);
int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
/* drawmesh.c */
void draw_mesh_textured(Scene *scene, View3D *v3d, Object *ob, struct DerivedMesh *dm, int faceselect);
/* view3d_draw.c */
void drawview3dspace(const bContext *C, ARegion *ar, View3D *v3d);
void draw_depth(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *));
int view3d_test_clipping(View3D *v3d, float *vec);
void view3d_clr_clipping(void);
void view3d_set_clipping(View3D *v3d);
void add_view3d_after(View3D *v3d, Base *base, int type, int flag);
void make_axis_color(char *col, char *col2, char axis);
void circf(float x, float y, float rad);
void circ(float x, float y, float rad);
void view3d_update_depths(ARegion *ar, View3D *v3d);
/* view3d_view.c */
float *give_cursor(Scene *scene, View3D *v3d);
void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]);
void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]);
void initgrabz(View3D *v3d, float x, float y, float z);
void window_to_3d(ARegion *ar, View3D *v3d, float *vec, short mx, short my);
int boundbox_clip(View3D *v3d, float obmat[][4], struct BoundBox *bb);
void view3d_project_short_clip(ARegion *ar, View3D *v3d, float *vec, short *adr, float projmat[4][4], float wmat[4][4]);
void view3d_project_short_noclip(ARegion *ar, float *vec, short *adr, float mat[4][4]);
void view3d_project_float(ARegion *a, float *vec, float *adr, float mat[4][4]);
void view3d_get_object_project_mat(View3D *v3d, struct Object *ob, float pmat[4][4], float vmat[4][4]);
void view3d_project_float(ARegion *ar, float *vec, float *adr, float mat[4][4]);
void project_short(ARegion *ar, View3D *v3d, float *vec, short *adr);
void project_int(ARegion *ar, View3D *v3d, float *vec, int *adr);
void project_int_noclip(ARegion *ar, View3D *v3d, float *vec, int *adr);
void project_short_noclip(ARegion *ar, View3D *v3d, float *vec, short *adr);
void project_float(ARegion *ar, View3D *v3d, float *vec, float *adr);
void project_float_noclip(ARegion *ar, View3D *v3d, float *vec, float *adr);
int get_view3d_viewplane(View3D *v3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, float *lens);
void obmat_to_viewmat(View3D *v3d, Object *ob, short smooth);
short view3d_opengl_select(bContext *C, Scene *scene, ARegion *ar, View3D *v3d, unsigned int *buffer, unsigned int bufsize, rcti *input);
void initlocalview(Scene *scene, ARegion *ar, View3D *v3d);
void restore_localviewdata(View3D *vd);
void endlocalview(Scene *scene, ScrArea *sa);
void setwinmatrixview3d(wmWindow *win, View3D *v3d, int winx, int winy, rctf *rect); /* rect: for picking */
void centerview(ARegion *ar, View3D *v3d);
void view3d_home(View3D *v3d, ARegion *ar, int center);
void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3]);
void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens);
void smooth_view_to_camera(View3D *v3d);
void setwinmatrixview3d(struct wmWindow *win, View3D *v3d, int winx, int winy, rctf *rect); /* rect: for picking */
void setviewmatrixview3d(View3D *v3d);
#endif /* ED_VIEW3D_INTERN_H */

View File

@@ -32,6 +32,7 @@
#include <float.h>
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_lamp_types.h"
#include "DNA_object_types.h"
@@ -48,10 +49,12 @@
#include "BLI_arithb.h"
#include "BLI_rand.h"
#include "BKE_anim.h"
#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
@@ -72,6 +75,7 @@
#include "view3d_intern.h" // own include
#define BL_NEAR_CLIP 0.001
float *give_cursor(Scene *scene, View3D *v3d)
{
@@ -79,6 +83,49 @@ float *give_cursor(Scene *scene, View3D *v3d)
else return scene->cursor;
}
/* create intersection coordinates in view Z direction at mouse coordinates */
void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3])
{
float vec[4];
if(v3d->persp != V3D_ORTHO){
vec[0]= 2.0f * mval[0] / ar->winx - 1;
vec[1]= 2.0f * mval[1] / ar->winy - 1;
vec[2]= -1.0f;
vec[3]= 1.0f;
Mat4MulVec4fl(v3d->persinv, vec);
VecMulf(vec, 1.0f / vec[3]);
VECCOPY(ray_start, v3d->viewinv[3]);
VECSUB(vec, vec, ray_start);
Normalize(vec);
VECADDFAC(ray_start, v3d->viewinv[3], vec, v3d->near);
VECADDFAC(ray_end, v3d->viewinv[3], vec, v3d->far);
}
else {
vec[0] = 2.0f * mval[0] / ar->winx - 1;
vec[1] = 2.0f * mval[1] / ar->winy - 1;
vec[2] = 0.0f;
vec[3] = 1.0f;
Mat4MulVec4fl(v3d->persinv, vec);
VECADDFAC(ray_start, vec, v3d->viewinv[2], 1000.0f);
VECADDFAC(ray_end, vec, v3d->viewinv[2], -1000.0f);
}
}
/* create intersection ray in view Z direction at mouse coordinates */
void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3])
{
float ray_end[3];
viewline(ar, v3d, mval, ray_start, ray_end);
VecSubf(ray_normal, ray_end, ray_start);
Normalize(ray_normal);
}
void initgrabz(View3D *v3d, float x, float y, float z)
@@ -110,6 +157,75 @@ void window_to_3d(ARegion *ar, View3D *v3d, float *vec, short mx, short my)
vec[2]= (v3d->persinv[0][2]*dx + v3d->persinv[1][2]*dy);
}
void view3d_get_object_project_mat(View3D *v3d, Object *ob, float pmat[4][4], float vmat[4][4])
{
Mat4MulMat4(vmat, ob->obmat, v3d->viewmat);
Mat4MulMat4(pmat, vmat, v3d->winmat);
Mat4CpyMat4(vmat, ob->obmat);
}
/* projectmat brings it to window coords, wmat to rotated world space */
void view3d_project_short_clip(ARegion *ar, View3D *v3d, float *vec, short *adr, float projmat[4][4], float wmat[4][4])
{
float fx, fy, vec4[4];
adr[0]= IS_CLIPPED;
/* clipplanes in eye space */
if(v3d->flag & V3D_CLIPPING) {
VECCOPY(vec4, vec);
Mat4MulVecfl(wmat, vec4);
if(view3d_test_clipping(v3d, vec4))
return;
}
VECCOPY(vec4, vec);
vec4[3]= 1.0;
Mat4MulVec4fl(projmat, vec4);
/* clipplanes in window space */
if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */
fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]);
if( fx>0 && fx<ar->winx) {
fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]);
if(fy>0.0 && fy< (float)ar->winy) {
adr[0]= (short)floor(fx);
adr[1]= (short)floor(fy);
}
}
}
}
void view3d_project_short_noclip(ARegion *ar, float *vec, short *adr, float mat[4][4])
{
float fx, fy, vec4[4];
adr[0]= IS_CLIPPED;
VECCOPY(vec4, vec);
vec4[3]= 1.0;
Mat4MulVec4fl(mat, vec4);
if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */
fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]);
if( fx>-32700 && fx<32700) {
fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]);
if(fy>-32700.0 && fy<32700.0) {
adr[0]= (short)floor(fx);
adr[1]= (short)floor(fy);
}
}
}
}
void view3d_project_float(ARegion *ar, float *vec, float *adr, float mat[4][4])
{
float vec4[4];
@@ -128,8 +244,40 @@ void view3d_project_float(ARegion *ar, float *vec, float *adr, float mat[4][4])
}
}
#define BL_NEAR_CLIP 0.001
int boundbox_clip(View3D *v3d, float obmat[][4], BoundBox *bb)
{
/* return 1: draw */
float mat[4][4];
float vec[4], min, max;
int a, flag= -1, fl;
if(bb==NULL) return 1;
if(bb->flag & OB_BB_DISABLED) return 1;
Mat4MulMat4(mat, obmat, v3d->persmat);
for(a=0; a<8; a++) {
VECCOPY(vec, bb->vec[a]);
vec[3]= 1.0;
Mat4MulVec4fl(mat, vec);
max= vec[3];
min= -vec[3];
fl= 0;
if(vec[0] < min) fl+= 1;
if(vec[0] > max) fl+= 2;
if(vec[1] < min) fl+= 4;
if(vec[1] > max) fl+= 8;
if(vec[2] < min) fl+= 16;
if(vec[2] > max) fl+= 32;
flag &= fl;
if(flag==0) return 1;
}
return 0;
}
void project_short(ARegion *ar, View3D *v3d, float *vec, short *adr) /* clips */
{
@@ -427,125 +575,9 @@ void setwinmatrixview3d(wmWindow *win, View3D *v3d, int winx, int winy, rctf *re
}
/* SMOOTHVIEW */
void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens)
{
/* View Animation enabled */
if (U.smooth_viewtx) {
int i;
char changed = 0;
float step = 0.0, step_inv;
float orig_dist;
float orig_lens;
float orig_quat[4];
float orig_ofs[3];
double time_allowed, time_current, time_start;
/* if there is no difference, return */
changed = 0; /* zero means no difference */
if (dist) {
if ((*dist) != v3d->dist)
changed = 1;
}
if (lens) {
if ((*lens) != v3d->lens)
changed = 1;
}
if (!changed && ofs) {
if ((ofs[0]!=v3d->ofs[0]) ||
(ofs[1]!=v3d->ofs[1]) ||
(ofs[2]!=v3d->ofs[2]) )
changed = 1;
}
if (!changed && quat ) {
if ((quat[0]!=v3d->viewquat[0]) ||
(quat[1]!=v3d->viewquat[1]) ||
(quat[2]!=v3d->viewquat[2]) ||
(quat[3]!=v3d->viewquat[3]) )
changed = 1;
}
/* The new view is different from the old one
* so animate the view */
if (changed) {
/* store original values */
VECCOPY(orig_ofs, v3d->ofs);
QUATCOPY(orig_quat, v3d->viewquat);
orig_dist = v3d->dist;
orig_lens = v3d->lens;
time_allowed= (float)U.smooth_viewtx / 1000.0;
time_current = time_start = PIL_check_seconds_timer();
/* if this is view rotation only
* we can decrease the time allowed by
* the angle between quats
* this means small rotations wont lag */
if (quat && !ofs && !dist) {
float vec1[3], vec2[3];
VECCOPY(vec1, quat);
VECCOPY(vec2, v3d->viewquat);
Normalize(vec1);
Normalize(vec2);
/* scale the time allowed by the rotation */
time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2);
}
while (time_start + time_allowed > time_current) {
step = (float)((time_current-time_start) / time_allowed);
/* ease in/out */
if (step < 0.5) step = (float)pow(step*2, 2)/2;
else step = (float)1-(pow(2*(1-step),2)/2);
step_inv = 1-step;
if (ofs)
for (i=0; i<3; i++)
v3d->ofs[i] = ofs[i]*step + orig_ofs[i]*step_inv;
if (quat)
QuatInterpol(v3d->viewquat, orig_quat, quat, step);
if (dist)
v3d->dist = ((*dist)*step) + (orig_dist*step_inv);
if (lens)
v3d->lens = ((*lens)*step) + (orig_lens*step_inv);
/*redraw the view*/
// scrarea_do_windraw(ar);
// screen_swapbuffers();
time_current= PIL_check_seconds_timer();
}
}
}
/* set these values even if animation is enabled because flaot
* error will make then not quite accurate */
if (ofs)
VECCOPY(v3d->ofs, ofs);
if (quat)
QUATCOPY(v3d->viewquat, quat);
if (dist)
v3d->dist = *dist;
if (lens)
v3d->lens = *lens;
}
/* Gets the lens and clipping values from a camera of lamp type object */
void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend)
static void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend)
{
if (!ob) return;
@@ -712,3 +744,674 @@ void setcameratoview3d(View3D *v3d)
/*}*/
v3d->viewquat[0]= -v3d->viewquat[0];
}
/* IGLuint-> GLuint*/
/* Warning: be sure to account for a negative return value
* This is an error, "Too many objects in select buffer"
* and no action should be taken (can crash blender) if this happens
*/
short view3d_opengl_select(bContext *C, Scene *scene, ARegion *ar, View3D *v3d, unsigned int *buffer, unsigned int bufsize, rcti *input)
{
rctf rect;
short code, hits;
G.f |= G_PICKSEL;
/* case not a border select */
if(input->xmin==input->xmax) {
rect.xmin= input->xmin-12; // seems to be default value for bones only now
rect.xmax= input->xmin+12;
rect.ymin= input->ymin-12;
rect.ymax= input->xmin+12;
}
else {
rect.xmin= input->xmin;
rect.xmax= input->xmax;
rect.ymin= input->ymin;
rect.ymax= input->ymax;
}
/* get rid of overlay button matrix XXX ?*/
setwinmatrixview3d(CTX_wm_window(C), v3d, ar->winx, ar->winy, &rect);
Mat4MulMat4(v3d->persmat, v3d->viewmat, v3d->winmat);
if(v3d->drawtype > OB_WIRE) {
v3d->zbuf= TRUE;
glEnable(GL_DEPTH_TEST);
}
if(v3d->flag & V3D_CLIPPING)
view3d_set_clipping(v3d);
glSelectBuffer( bufsize, (GLuint *)buffer);
glRenderMode(GL_SELECT);
glInitNames(); /* these two calls whatfor? It doesnt work otherwise */
glPushName(-1);
code= 1;
if(G.obedit && G.obedit->type==OB_MBALL) {
draw_object(C, scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
}
else if ((G.obedit && G.obedit->type==OB_ARMATURE)) {
draw_object(C, scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
}
else {
Base *base;
v3d->xray= TRUE; // otherwise it postpones drawing
for(base= scene->base.first; base; base= base->next) {
if(base->lay & v3d->lay) {
if (base->object->restrictflag & OB_RESTRICT_SELECT)
base->selcol= 0;
else {
base->selcol= code;
glLoadName(code);
draw_object(C, scene, ar, v3d, base, DRAW_PICKING|DRAW_CONSTCOLOR);
/* we draw group-duplicators for selection too */
if((base->object->transflag & OB_DUPLI) && base->object->dup_group) {
ListBase *lb;
DupliObject *dob;
Base tbase;
tbase.flag= OB_FROMDUPLI;
lb= object_duplilist(scene, base->object);
for(dob= lb->first; dob; dob= dob->next) {
tbase.object= dob->ob;
Mat4CpyMat4(dob->ob->obmat, dob->mat);
draw_object(C, scene, ar, v3d, &tbase, DRAW_PICKING|DRAW_CONSTCOLOR);
Mat4CpyMat4(dob->ob->obmat, dob->omat);
}
free_object_duplilist(lb);
}
code++;
}
}
}
v3d->xray= FALSE; // restore
}
glPopName(); /* see above (pushname) */
hits= glRenderMode(GL_RENDER);
G.f &= ~G_PICKSEL;
setwinmatrixview3d(CTX_wm_window(C), v3d, ar->winx, ar->winy, NULL);
Mat4MulMat4(v3d->persmat, v3d->viewmat, v3d->winmat);
if(v3d->drawtype > OB_WIRE) {
v3d->zbuf= 0;
glDisable(GL_DEPTH_TEST);
}
// XXX persp(PERSP_WIN);
if(v3d->flag & V3D_CLIPPING)
view3d_clr_clipping();
if(hits<0) printf("Too many objects in select buffer\n"); // XXX make error message
return hits;
}
// XXX solve: localview on region level? no.... layers are area, so all regions in area have to be set
static unsigned int free_localbit(void)
{
unsigned int lay;
ScrArea *sa;
bScreen *sc;
lay= 0;
/* sometimes we loose a localview: when an area is closed */
/* check all areas: which localviews are in use? */
for(sc= G.main->screen.first; sc; sc= sc->id.next) {
for(sa= sc->areabase.first; sa; sa= sa->next) {
SpaceLink *sl= sa->spacedata.first;
for(; sl; sl= sl->next) {
if(sl->spacetype==SPACE_VIEW3D) {
View3D *v3d= (View3D*) sl;
lay |= v3d->lay;
}
}
}
}
if( (lay & 0x01000000)==0) return 0x01000000;
if( (lay & 0x02000000)==0) return 0x02000000;
if( (lay & 0x04000000)==0) return 0x04000000;
if( (lay & 0x08000000)==0) return 0x08000000;
if( (lay & 0x10000000)==0) return 0x10000000;
if( (lay & 0x20000000)==0) return 0x20000000;
if( (lay & 0x40000000)==0) return 0x40000000;
if( (lay & 0x80000000)==0) return 0x80000000;
return 0;
}
void initlocalview(Scene *scene, ARegion *ar, View3D *v3d)
{
Base *base;
float size = 0.0, min[3], max[3], afm[3];
unsigned int locallay;
int ok=0;
if(v3d->localvd) return;
INIT_MINMAX(min, max);
locallay= free_localbit();
if(locallay==0) {
printf("Sorry, no more than 8 localviews\n"); // XXX error
ok= 0;
}
else {
if(G.obedit) {
minmax_object(G.obedit, min, max);
ok= 1;
BASACT->lay |= locallay;
G.obedit->lay= BASACT->lay;
}
else {
base= FIRSTBASE;
while(base) {
if TESTBASE(base) {
minmax_object(base->object, min, max);
base->lay |= locallay;
base->object->lay= base->lay;
ok= 1;
}
base= base->next;
}
}
afm[0]= (max[0]-min[0]);
afm[1]= (max[1]-min[1]);
afm[2]= (max[2]-min[2]);
size= 0.7*MAX3(afm[0], afm[1], afm[2]);
if(size<=0.01) size= 0.01;
}
if(ok) {
v3d->localvd= MEM_mallocN(sizeof(View3D), "localview");
memcpy(v3d->localvd, v3d, sizeof(View3D));
v3d->ofs[0]= -(min[0]+max[0])/2.0;
v3d->ofs[1]= -(min[1]+max[1])/2.0;
v3d->ofs[2]= -(min[2]+max[2])/2.0;
v3d->dist= size;
// correction for window aspect ratio
if(ar->winy>2 && ar->winx>2) {
size= (float)ar->winx/(float)ar->winy;
if(size<1.0) size= 1.0/size;
v3d->dist*= size;
}
if (v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP;
if (v3d->near> 0.1) v3d->near= 0.1;
v3d->cursor[0]= -v3d->ofs[0];
v3d->cursor[1]= -v3d->ofs[1];
v3d->cursor[2]= -v3d->ofs[2];
v3d->lay= locallay;
// XXX countall();
// XXX scrarea_queue_winredraw(curarea);
}
else {
/* clear flags */
base= FIRSTBASE;
while(base) {
if( base->lay & locallay ) {
base->lay-= locallay;
if(base->lay==0) base->lay= v3d->layact;
if(base->object != G.obedit) base->flag |= SELECT;
base->object->lay= base->lay;
}
base= base->next;
}
// XXX scrarea_queue_headredraw(curarea);
v3d->localview= 0;
}
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
}
void centerview(ARegion *ar, View3D *v3d) /* like a localview without local! */
{
Object *ob= OBACT;
float size, min[3], max[3], afm[3];
int ok=0;
/* SMOOTHVIEW */
float new_ofs[3];
float new_dist;
INIT_MINMAX(min, max);
if (G.f & G_WEIGHTPAINT) {
/* hardcoded exception, we look for the one selected armature */
/* this is weak code this way, we should make a generic active/selection callback interface once... */
Base *base;
for(base=FIRSTBASE; base; base= base->next) {
if(TESTBASELIB(base)) {
if(base->object->type==OB_ARMATURE)
if(base->object->flag & OB_POSEMODE)
break;
}
}
if(base)
ob= base->object;
}
if(G.obedit) {
// XXX ok = minmax_verts(min, max); /* only selected */
}
else if(ob && (ob->flag & OB_POSEMODE)) {
if(ob->pose) {
bArmature *arm= ob->data;
bPoseChannel *pchan;
float vec[3];
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone->flag & BONE_SELECTED) {
if(pchan->bone->layer & arm->layer) {
ok= 1;
VECCOPY(vec, pchan->pose_head);
Mat4MulVecfl(ob->obmat, vec);
DO_MINMAX(vec, min, max);
VECCOPY(vec, pchan->pose_tail);
Mat4MulVecfl(ob->obmat, vec);
DO_MINMAX(vec, min, max);
}
}
}
}
}
else if (FACESEL_PAINT_TEST) {
// XXX ok= minmax_tface(min, max);
}
else if (G.f & G_PARTICLEEDIT) {
// XXX ok= PE_minmax(min, max);
}
else {
Base *base= FIRSTBASE;
while(base) {
if TESTBASE(base) {
minmax_object(base->object, min, max);
/* account for duplis */
minmax_object_duplis(base->object, min, max);
ok= 1;
}
base= base->next;
}
}
if(ok==0) return;
afm[0]= (max[0]-min[0]);
afm[1]= (max[1]-min[1]);
afm[2]= (max[2]-min[2]);
size= 0.7f*MAX3(afm[0], afm[1], afm[2]);
if(size <= v3d->near*1.5f) size= v3d->near*1.5f;
new_ofs[0]= -(min[0]+max[0])/2.0f;
new_ofs[1]= -(min[1]+max[1])/2.0f;
new_ofs[2]= -(min[2]+max[2])/2.0f;
new_dist = size;
/* correction for window aspect ratio */
if(ar->winy>2 && ar->winx>2) {
size= (float)ar->winx/(float)ar->winy;
if(size<1.0f) size= 1.0f/size;
new_dist*= size;
}
v3d->cursor[0]= -new_ofs[0];
v3d->cursor[1]= -new_ofs[1];
v3d->cursor[2]= -new_ofs[2];
if (v3d->persp==V3D_CAMOB && v3d->camera) {
float orig_lens= v3d->lens;
v3d->persp=V3D_PERSP;
v3d->dist= 0.0f;
view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, new_ofs, NULL, &new_dist, &orig_lens);
} else {
if(v3d->persp==V3D_CAMOB)
v3d->persp= V3D_PERSP;
smooth_view(v3d, new_ofs, NULL, &new_dist, NULL);
}
// XXX scrarea_queue_winredraw(curarea);
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
}
void restore_localviewdata(View3D *vd)
{
if(vd->localvd==0) return;
VECCOPY(vd->ofs, vd->localvd->ofs);
vd->dist= vd->localvd->dist;
vd->persp= vd->localvd->persp;
vd->view= vd->localvd->view;
vd->near= vd->localvd->near;
vd->far= vd->localvd->far;
vd->lay= vd->localvd->lay;
vd->layact= vd->localvd->layact;
vd->drawtype= vd->localvd->drawtype;
vd->camera= vd->localvd->camera;
QUATCOPY(vd->viewquat, vd->localvd->viewquat);
}
void endlocalview(Scene *scene, ScrArea *sa)
{
View3D *v3d;
struct Base *base;
unsigned int locallay;
if(sa->spacetype!=SPACE_VIEW3D) return;
v3d= sa->spacedata.first;
if(v3d->localvd) {
locallay= v3d->lay & 0xFF000000;
restore_localviewdata(v3d);
MEM_freeN(v3d->localvd);
v3d->localvd= 0;
v3d->localview= 0;
/* for when in other window the layers have changed */
if(v3d->scenelock) v3d->lay= scene->lay;
base= FIRSTBASE;
while(base) {
if( base->lay & locallay ) {
base->lay-= locallay;
if(base->lay==0) base->lay= v3d->layact;
if(base->object != G.obedit) {
base->flag |= SELECT;
base->object->flag |= SELECT;
}
base->object->lay= base->lay;
}
base= base->next;
}
// XXX countall();
// XXX allqueue(REDRAWVIEW3D, 0); /* because of select */
// XXX allqueue(REDRAWOOPS, 0); /* because of select */
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
}
}
void view3d_home(View3D *v3d, ARegion *ar, int center)
{
Base *base;
float size, min[3], max[3], afm[3];
int ok= 1, onedone=0;
if(center) {
min[0]= min[1]= min[2]= 0.0f;
max[0]= max[1]= max[2]= 0.0f;
}
else {
INIT_MINMAX(min, max);
}
for(base= FIRSTBASE; base; base= base->next) {
if(base->lay & v3d->lay) {
onedone= 1;
minmax_object(base->object, min, max);
}
}
if(!onedone) return;
afm[0]= (max[0]-min[0]);
afm[1]= (max[1]-min[1]);
afm[2]= (max[2]-min[2]);
size= 0.7f*MAX3(afm[0], afm[1], afm[2]);
if(size==0.0) ok= 0;
if(ok) {
float new_dist;
float new_ofs[3];
new_dist = size;
new_ofs[0]= -(min[0]+max[0])/2.0f;
new_ofs[1]= -(min[1]+max[1])/2.0f;
new_ofs[2]= -(min[2]+max[2])/2.0f;
// correction for window aspect ratio
if(ar->winy>2 && ar->winx>2) {
size= (float)ar->winx/(float)ar->winy;
if(size<1.0) size= 1.0f/size;
new_dist*= size;
}
if (v3d->persp==V3D_CAMOB && v3d->camera) {
/* switch out of camera view */
float orig_lens= v3d->lens;
v3d->persp= V3D_PERSP;
v3d->dist= 0.0;
view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, new_ofs, NULL, &new_dist, &orig_lens);
} else {
if(v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP;
smooth_view(v3d, new_ofs, NULL, &new_dist, NULL);
}
// XXX scrarea_queue_winredraw(curarea);
}
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
}
void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3])
{
float alignaxis[3] = {0.0, 0.0, 0.0};
float norm[3], axis[3], angle, new_quat[4];
if(axisidx > 0) alignaxis[axisidx-1]= 1.0;
else alignaxis[-axisidx-1]= -1.0;
VECCOPY(norm, vec);
Normalize(norm);
angle= (float)acos(Inpf(alignaxis, norm));
Crossf(axis, alignaxis, norm);
VecRotToQuat(axis, -angle, new_quat);
v3d->view= 0;
if (v3d->persp==V3D_CAMOB && v3d->camera) {
/* switch out of camera view */
float orig_ofs[3];
float orig_dist= v3d->dist;
float orig_lens= v3d->lens;
VECCOPY(orig_ofs, v3d->ofs);
v3d->persp= V3D_PERSP;
v3d->dist= 0.0;
view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, orig_ofs, new_quat, &orig_dist, &orig_lens);
} else {
if (v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP; /* switch out of camera mode */
smooth_view(v3d, NULL, new_quat, NULL, NULL);
}
}
/* SMOOTHVIEW */
void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens)
{
/* View Animation enabled */
if (U.smooth_viewtx) {
int i;
char changed = 0;
float step = 0.0, step_inv;
float orig_dist;
float orig_lens;
float orig_quat[4];
float orig_ofs[3];
double time_allowed, time_current, time_start;
/* if there is no difference, return */
changed = 0; /* zero means no difference */
if (dist) {
if ((*dist) != v3d->dist)
changed = 1;
}
if (lens) {
if ((*lens) != v3d->lens)
changed = 1;
}
if (!changed && ofs) {
if ((ofs[0]!=v3d->ofs[0]) ||
(ofs[1]!=v3d->ofs[1]) ||
(ofs[2]!=v3d->ofs[2]) )
changed = 1;
}
if (!changed && quat ) {
if ((quat[0]!=v3d->viewquat[0]) ||
(quat[1]!=v3d->viewquat[1]) ||
(quat[2]!=v3d->viewquat[2]) ||
(quat[3]!=v3d->viewquat[3]) )
changed = 1;
}
/* The new view is different from the old one
* so animate the view */
if (changed) {
/* store original values */
VECCOPY(orig_ofs, v3d->ofs);
QUATCOPY(orig_quat, v3d->viewquat);
orig_dist = v3d->dist;
orig_lens = v3d->lens;
time_allowed= (float)U.smooth_viewtx / 1000.0;
time_current = time_start = PIL_check_seconds_timer();
/* if this is view rotation only
* we can decrease the time allowed by
* the angle between quats
* this means small rotations wont lag */
if (quat && !ofs && !dist) {
float vec1[3], vec2[3];
VECCOPY(vec1, quat);
VECCOPY(vec2, v3d->viewquat);
Normalize(vec1);
Normalize(vec2);
/* scale the time allowed by the rotation */
time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2);
}
while (time_start + time_allowed > time_current) {
step = (float)((time_current-time_start) / time_allowed);
/* ease in/out */
if (step < 0.5) step = (float)pow(step*2, 2)/2;
else step = (float)1-(pow(2*(1-step),2)/2);
step_inv = 1-step;
if (ofs)
for (i=0; i<3; i++)
v3d->ofs[i] = ofs[i]*step + orig_ofs[i]*step_inv;
if (quat)
QuatInterpol(v3d->viewquat, orig_quat, quat, step);
if (dist)
v3d->dist = ((*dist)*step) + (orig_dist*step_inv);
if (lens)
v3d->lens = ((*lens)*step) + (orig_lens*step_inv);
/*redraw the view*/
// scrarea_do_windraw(ar);
// screen_swapbuffers();
time_current= PIL_check_seconds_timer();
}
}
}
/* set these values even if animation is enabled because flaot
* error will make then not quite accurate */
if (ofs)
VECCOPY(v3d->ofs, ofs);
if (quat)
QUATCOPY(v3d->viewquat, quat);
if (dist)
v3d->dist = *dist;
if (lens)
v3d->lens = *lens;
}
/* For use with smooth view
*
* the current view is unchanged, blend between the current view and the
* camera view
* */
void smooth_view_to_camera(View3D *v3d)
{
if (!U.smooth_viewtx || !v3d->camera || v3d->persp != V3D_CAMOB) {
return;
} else {
Object *ob = v3d->camera;
float orig_ofs[3];
float orig_dist=v3d->dist;
float orig_lens=v3d->lens;
float new_dist=0.0;
float new_lens=35.0;
float new_quat[4];
float new_ofs[3];
VECCOPY(orig_ofs, v3d->ofs);
view_settings_from_ob(ob, new_ofs, new_quat, NULL, &new_lens);
v3d->persp= V3D_PERSP;
smooth_view(v3d, new_ofs, new_quat, &new_dist, &new_lens);
VECCOPY(v3d->ofs, orig_ofs);
v3d->lens= orig_lens;
v3d->dist = orig_dist; /* restore the dist */
v3d->camera = ob;
v3d->persp= V3D_CAMOB;
}
}

View File

@@ -9,7 +9,7 @@ sources = env.Glob('intern/*.c')
incs = '. ../editors/include ../python ../makesdna ../blenlib ../blenkernel'
incs += ' ../nodes ../imbuf ../blenloader ../render/extern/include'
incs += ' ../ftfont ../radiosity/extern/include ../../kernel/gen_system'
incs += ' ../makesrna'
incs += ' ../makesrna ../gpu'
incs += ' #/intern/guardedalloc #/intern/memutil #/intern/ghost #/intern/bmfont'
incs += ' #/intern/elbeem #/extern/glew/include'

View File

@@ -138,6 +138,8 @@ void wmFrustum (wmWindow *win, float x1, float x2, float y1, float y2, float
void wmOrtho (wmWindow *win, float x1, float x2, float y1, float y2, float n, float f);
void wmOrtho2 (wmWindow *win, float x1, float x2, float y1, float y2);
/* utilities */
void WM_set_framebuffer_index_color(int index);
#endif /* WM_API_H */

View File

@@ -57,6 +57,7 @@ CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../nodes
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../blenloader
CPPFLAGS += -I../../gpu
CPPFLAGS += -I../../render/extern/include
CPPFLAGS += -I../../ftfont
CPPFLAGS += -I../../radiosity/extern/include

View File

@@ -69,8 +69,6 @@
#include "SYS_System.h"
#include "UI_interface.h"
#include "RNA_define.h"
#include "WM_api.h"
@@ -84,6 +82,12 @@
#include "ED_screen.h"
#include "UI_interface.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
static void initbuttons(void)
{
UI_init();
@@ -135,7 +139,9 @@ void WM_init(bContext *C)
// XXX UI_filelist_init_icons();
// init_gl_stuff(); /* drawview.c, after homefile */
GPU_state_init();
GPU_extensions_init();
read_Blog();
BLI_strncpy(G.lib, G.sce, FILE_MAX);
}

View File

@@ -445,7 +445,7 @@ static unsigned int index_to_framebuffer(int index)
#endif
void set_framebuffer_index_color(int index)
void WM_set_framebuffer_index_color(int index)
{
cpack(index_to_framebuffer(index));
}