2.5
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:
110
source/blender/editors/include/BIF_retopo.h
Normal file
110
source/blender/editors/include/BIF_retopo.h
Normal 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
|
||||
@@ -31,6 +31,7 @@
|
||||
/* **************** GENERAL EDITOR-WIDE TYPES AND DEFINES ************************** */
|
||||
|
||||
/* old blender defines... should be depricated? */
|
||||
#define DESELECT 0
|
||||
#define SELECT 1
|
||||
#define ACTIVE 2
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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] )
|
||||
|
||||
579
source/blender/editors/space_view3d/drawmesh.c
Normal file
579
source/blender/editors/space_view3d/drawmesh.c
Normal 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);
|
||||
}
|
||||
|
||||
5475
source/blender/editors/space_view3d/drawobject.c
Normal file
5475
source/blender/editors/space_view3d/drawobject.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
1086
source/blender/editors/space_view3d/view3d_edit.c
Normal file
1086
source/blender/editors/space_view3d/view3d_edit.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
int boundbox_clip(View3D *v3d, float obmat[][4], BoundBox *bb)
|
||||
{
|
||||
/* return 1: draw */
|
||||
|
||||
#define BL_NEAR_CLIP 0.001
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user