Initial revision
This commit is contained in:
37
source/blender/radiosity/Makefile
Normal file
37
source/blender/radiosity/Makefile
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
# Foundation also sells licenses for use in proprietary software under
|
||||
# the Blender License. See http://www.blender.org/BL/ for information
|
||||
# about this.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
#
|
||||
# Makes module object directory and bounces make to subdirectories.
|
||||
|
||||
SOURCEDIR = source/blender/radiosity
|
||||
DIRS = intern
|
||||
|
||||
include nan_subdirs.mk
|
170
source/blender/radiosity/extern/include/radio.h
vendored
Normal file
170
source/blender/radiosity/extern/include/radio.h
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
/* ***************************************
|
||||
|
||||
|
||||
|
||||
radio.h nov/dec 1992
|
||||
revised for Blender may 1999
|
||||
|
||||
$Id$
|
||||
|
||||
***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
Foundation also sells licenses for use in proprietary software under
|
||||
the Blender License. See http://www.blender.org/BL/ for information
|
||||
about this.
|
||||
|
||||
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.
|
||||
|
||||
The Original Code is: all of this file.
|
||||
|
||||
Contributor(s): none yet.
|
||||
|
||||
***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef RADIO_H
|
||||
#define RADIO_H
|
||||
#define RADIO_H
|
||||
|
||||
/* type include */
|
||||
#include "radio_types.h"
|
||||
|
||||
extern RadGlobal RG;
|
||||
|
||||
/* radfactors.c */
|
||||
extern float calcStokefactor(RPatch *shoot, RPatch *rp, RNode *rn, float *area);
|
||||
extern void calcTopfactors(void);
|
||||
void calcSidefactors(void);
|
||||
extern void initradiosity(void);
|
||||
extern void rad_make_hocos(RadView *vw);
|
||||
extern void hemizbuf(RadView *vw);
|
||||
extern int makeformfactors(RPatch *shoot);
|
||||
extern void applyformfactors(RPatch *shoot);
|
||||
extern RPatch *findshootpatch(void);
|
||||
extern void setnodeflags(RNode *rn, int flag, int set);
|
||||
extern void backface_test(RPatch *shoot);
|
||||
extern void clear_backface_test(void);
|
||||
extern void progressiverad(void);
|
||||
extern void minmaxradelem(RNode *rn, float *min, float *max);
|
||||
extern void minmaxradelemfilt(RNode *rn, float *min, float *max, float *errmin, float *errmax);
|
||||
extern void subdivideshootElements(int it);
|
||||
extern void subdivideshootPatches(int it);
|
||||
extern void inithemiwindows(void);
|
||||
extern void closehemiwindows(void);
|
||||
void rad_init_energy(void);
|
||||
|
||||
/* radio.c */
|
||||
void freeAllRad(void);
|
||||
int rad_phase(void);
|
||||
void rad_status_str(char *str);
|
||||
void rad_printstatus(void);
|
||||
void rad_setlimits(void);
|
||||
void set_radglobal(void);
|
||||
void add_radio(void);
|
||||
void delete_radio(void);
|
||||
int rad_go(void);
|
||||
void rad_subdivshootpatch(void);
|
||||
void rad_subdivshootelem(void);
|
||||
void rad_limit_subdivide(void);
|
||||
|
||||
/* radnode.c */
|
||||
extern void setnodelimit(float limit);
|
||||
extern float *mallocVert(void);
|
||||
extern float *callocVert(void);
|
||||
extern void freeVert(float *vert);
|
||||
extern RNode *mallocNode(void);
|
||||
extern RNode *callocNode(void);
|
||||
extern void freeNode(RNode *node);
|
||||
extern void freeNode_recurs(RNode *node);
|
||||
extern RPatch *mallocPatch(void);
|
||||
extern RPatch *callocPatch(void);
|
||||
extern void freePatch(RPatch *patch);
|
||||
extern void replaceAllNode(RNode *, RNode *);
|
||||
extern void replaceAllNodeInv(RNode *neighb, RNode *old);
|
||||
extern void replaceAllNodeUp(RNode *neighb, RNode *old);
|
||||
extern void replaceTestNode(RNode *, RNode **, RNode *, int , float *);
|
||||
extern void free_fastAll(void);
|
||||
|
||||
/* radnode.c */
|
||||
extern void start_fastmalloc(char *str);
|
||||
extern int setvertexpointersNode(RNode *neighb, RNode *node, int level, float **v1, float **v2);
|
||||
extern float edlen(float *v1, float *v2);
|
||||
extern void deleteNodes(RNode *node);
|
||||
extern void subdivideTriNode(RNode *node, RNode *edge);
|
||||
extern void subdivideNode(RNode *node, RNode *edge);
|
||||
extern int comparelevel(RNode *node, RNode *nb, int level);
|
||||
|
||||
/* radpreprocess.c */
|
||||
extern void splitconnected(void);
|
||||
extern int vergedge(const void *v1,const void *v2);
|
||||
extern void addedge(float *v1, float *v2, EdSort *es);
|
||||
extern void setedgepointers(void);
|
||||
extern void rad_collect_meshes(void);
|
||||
extern void countelem(RNode *rn);
|
||||
extern void countglobaldata(void);
|
||||
extern void addelem(RNode ***el, RNode *rn, RPatch *rp);
|
||||
extern void makeGlobalElemArray(void);
|
||||
extern void remakeGlobaldata(void);
|
||||
extern void splitpatch(RPatch *old);
|
||||
extern void addpatch(RPatch *old, RNode *rn);
|
||||
extern void converttopatches(void);
|
||||
extern void make_elements(void);
|
||||
extern void subdividelamps(void);
|
||||
extern void maxsizePatches(void);
|
||||
extern void subdiv_elements(void);
|
||||
|
||||
/* radpostprocess.c */
|
||||
void addaccu(register char *z, register char *t);
|
||||
void addaccuweight(register char *z, register char *t, int w);
|
||||
void triaweight(Face *face, int *w1, int *w2, int *w3);
|
||||
void init_face_tab(void);
|
||||
Face *addface(void);
|
||||
void makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn);
|
||||
void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag);
|
||||
void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag);
|
||||
float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2);
|
||||
void make_face_tab(void);
|
||||
void filterFaces(void);
|
||||
void calcfiltrad(RNode *rn, float *cd);
|
||||
void filterNodes(void);
|
||||
void removeEqualNodes(short limit);
|
||||
void rad_addmesh(void);
|
||||
void rad_replacemesh(void);
|
||||
|
||||
/* raddisplay.c */
|
||||
extern char calculatecolor(float col);
|
||||
extern void make_node_display(void);
|
||||
extern void drawnodeWire(RNode *rn);
|
||||
extern void drawsingnodeWire(RNode *rn);
|
||||
extern void drawnodeSolid(RNode *rn);
|
||||
extern void drawnodeGour(RNode *rn);
|
||||
extern void drawpatch(RPatch *patch, unsigned int col);
|
||||
extern void drawnode_ext(RNode *rn, unsigned int col);
|
||||
extern void drawOverflowElem(void);
|
||||
extern void drawfaceGour(Face *face);
|
||||
extern void drawfaceSolid(Face *face);
|
||||
extern void drawfaceWire(Face *face);
|
||||
extern void drawsquare(float *cent, float size, short cox, short coy);
|
||||
extern void drawlimits(void);
|
||||
extern void setcolNode(RNode *rn, unsigned int *col);
|
||||
extern void pseudoAmb(void);
|
||||
extern void rad_forcedraw(void);
|
||||
extern void drawpatch_ext(RPatch *patch, unsigned int col);
|
||||
|
||||
extern void RAD_drawall(int depth_is_on);
|
||||
|
||||
#endif /* RADIO_H */
|
174
source/blender/radiosity/extern/include/radio_types.h
vendored
Normal file
174
source/blender/radiosity/extern/include/radio_types.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* radio_types.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* #include "misc_util.h" */ /* for listbase...*/
|
||||
|
||||
|
||||
#ifndef RADIO_TYPES_H
|
||||
#define RADIO_TYPES_H
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#define DTWIRE 0
|
||||
#define DTGOUR 2
|
||||
#define DTSOLID 1
|
||||
|
||||
#define PI M_PI
|
||||
#define RAD_MAXFACETAB 1024
|
||||
#define RAD_NEXTFACE(a) if( ((a) & 1023)==0 ) face= RG.facebase[(a)>>10]; else face++;
|
||||
|
||||
/* RG.phase */
|
||||
#define RAD_SHOOTE 1
|
||||
#define RAD_SHOOTP 2
|
||||
#define RAD_SOLVE 3
|
||||
|
||||
typedef struct RadView {
|
||||
float cam[3], tar[3], up[3];
|
||||
float wx1, wx2, wy1, wy2;
|
||||
float mynear, myfar;
|
||||
float viewmat[4][4], winmat[4][4];
|
||||
unsigned int *rect, *rectz;
|
||||
short rectx, recty;
|
||||
int wid;
|
||||
|
||||
} RadView;
|
||||
|
||||
/* rn->f */
|
||||
#define RAD_PATCH 1
|
||||
#define RAD_SHOOT 2
|
||||
#define RAD_SUBDIV 4
|
||||
#define RAD_BACKFACE 8
|
||||
|
||||
|
||||
typedef struct RNode { /* lengte: 76 */
|
||||
struct RNode *down1, *down2, *up;
|
||||
struct RNode *ed1, *ed2, *ed3, *ed4;
|
||||
struct RPatch *par;
|
||||
|
||||
char lev1, lev2, lev3, lev4; /* edgelevels */
|
||||
short type; /* type: 4==QUAD, 3==TRIA */
|
||||
short f;
|
||||
float *v1, *v2, *v3, *v4;
|
||||
float totrad[3], area;
|
||||
|
||||
unsigned int col;
|
||||
} RNode;
|
||||
|
||||
|
||||
typedef struct Elem { /* lengte: 44 */
|
||||
struct RPatch *par;
|
||||
|
||||
short type; /* type: 4==QUAD, 3==TRIA */
|
||||
short f; /* bit 0: patch, bit 1: shootelement */
|
||||
float *v1, *v2, *v3, *v4;
|
||||
float totrad[3], area;
|
||||
|
||||
unsigned int col;
|
||||
} Elem;
|
||||
|
||||
|
||||
typedef struct Face { /* lengte: 24 */
|
||||
float *v1, *v2, *v3, *v4;
|
||||
unsigned int col, matindex;
|
||||
} Face;
|
||||
|
||||
/* rp->f1 */
|
||||
#define RAD_NO_SPLIT 1
|
||||
|
||||
typedef struct RPatch {
|
||||
struct RPatch *next, *prev;
|
||||
RNode *first; /* first node==patch */
|
||||
|
||||
struct Object *from;
|
||||
|
||||
int type; /* 3: TRIA, 4: QUAD */
|
||||
short f, f1; /* flags f: als node, alleen subdiv */
|
||||
|
||||
float ref[3], emit[3], unshot[3];
|
||||
float cent[3], norm[3];
|
||||
float area;
|
||||
int matindex;
|
||||
|
||||
} RPatch;
|
||||
|
||||
|
||||
typedef struct VeNoCo { /* nodig voor splitconnected */
|
||||
struct VeNoCo *next;
|
||||
float *v;
|
||||
float *n;
|
||||
float *col;
|
||||
int flag;
|
||||
} VeNoCo;
|
||||
|
||||
|
||||
typedef struct EdSort { /* sorteren edges */
|
||||
float *v1, *v2;
|
||||
RNode *node;
|
||||
int nr;
|
||||
} EdSort;
|
||||
|
||||
typedef struct {
|
||||
struct Radio *radio;
|
||||
unsigned int *hemibuf;
|
||||
struct ListBase patchbase;
|
||||
int totpatch, totelem, totvert, totlamp;
|
||||
RNode **elem; /* globaal array van alle pointers */
|
||||
VeNoCo *verts; /* tijdelijk vertices van patches */
|
||||
float *formfactors; /* een factor per element */
|
||||
float *topfactors, *sidefactors; /* LUT voor delta's */
|
||||
int *index; /* LUT voor bovenstaande LUT */
|
||||
Face **facebase;
|
||||
int totface;
|
||||
float min[3], max[3], size[3], cent[3]; /* world */
|
||||
float maxsize, totenergy;
|
||||
float patchmin, patchmax;
|
||||
float elemmin, elemmax;
|
||||
float radfactor, lostenergy, igamma; /* radfac zit in button, radfactor wordt berekend */
|
||||
int phase;
|
||||
/* to preserve materials as used before, max 16 */
|
||||
Material *matar[MAXMAT];
|
||||
int totmat;
|
||||
|
||||
/* this part is a copy of struct Radio */
|
||||
short hemires, maxiter;
|
||||
short drawtype, flag; /* bit 0 en 1: limits laten zien */
|
||||
short subshootp, subshoote, nodelim, maxsublamp;
|
||||
int maxnode;
|
||||
float convergence;
|
||||
float radfac, gamma; /* voor afbeelden */
|
||||
|
||||
} RadGlobal;
|
||||
|
||||
#endif /* radio_types.h */
|
37
source/blender/radiosity/intern/Makefile
Normal file
37
source/blender/radiosity/intern/Makefile
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
# Foundation also sells licenses for use in proprietary software under
|
||||
# the Blender License. See http://www.blender.org/BL/ for information
|
||||
# about this.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
#
|
||||
# Makes module object directory and bounces make to subdirectories.
|
||||
|
||||
SOURCEDIR = source/blender/radiosity/intern
|
||||
DIRS = source
|
||||
|
||||
include nan_subdirs.mk
|
60
source/blender/radiosity/intern/source/Makefile
Normal file
60
source/blender/radiosity/intern/source/Makefile
Normal file
@@ -0,0 +1,60 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
# Foundation also sells licenses for use in proprietary software under
|
||||
# the Blender License. See http://www.blender.org/BL/ for information
|
||||
# about this.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
#
|
||||
# radiosity uses the render lib
|
||||
#
|
||||
|
||||
LIBNAME = radiosity
|
||||
DIR = $(OCGDIR)/blender/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
|
||||
CFLAGS += -funsigned-char
|
||||
endif
|
||||
|
||||
CFLAGS += $(LEVEL_1_C_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I$(OPENGL_HEADERS)
|
||||
|
||||
# not very neat....
|
||||
CPPFLAGS += -I../../../blenkernel
|
||||
CPPFLAGS += -I../../../blenlib
|
||||
CPPFLAGS += -I../../../makesdna
|
||||
CPPFLAGS += -I../../../imbuf
|
||||
CPPFLAGS += -I../../../
|
||||
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
||||
|
||||
# first /include is my own includes, second are the external includes
|
||||
# third is the external interface. there should be a nicer way to say this
|
||||
CPPFLAGS += -I../include -I../../../include -I../../extern/include
|
||||
CPPFLAGS += -I../../../render/extern/include -I../../../misc
|
||||
|
527
source/blender/radiosity/intern/source/raddisplay.c
Normal file
527
source/blender/radiosity/intern/source/raddisplay.c
Normal file
@@ -0,0 +1,527 @@
|
||||
/* ***************************************
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
|
||||
|
||||
|
||||
raddisplay.c nov/dec 1992
|
||||
may 1999
|
||||
|
||||
- drawing
|
||||
- color calculation for display during solving
|
||||
|
||||
$Id$
|
||||
|
||||
*************************************** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_mywindow.h"
|
||||
|
||||
#include "radio.h"
|
||||
|
||||
/* Mij afspraak is cpack een getal dat als 0xFFaa66 of zo kan worden
|
||||
* uitgedrukt. Is dus gevoelig voor endian. Met deze define wordt het
|
||||
* altijd goed afgebeeld */
|
||||
#define cpack(x) glColor3ub( ((x)&0xFF), (((x)>>8)&0xFF), (((x)>>16)&0xFF) )
|
||||
|
||||
char calculatecolor(float col)
|
||||
{
|
||||
int b;
|
||||
|
||||
if(RG.gamma==1.0) {
|
||||
b= RG.radfactor*col;
|
||||
}
|
||||
else if(RG.gamma==2.0) {
|
||||
b= RG.radfactor*sqrt(col);
|
||||
}
|
||||
else {
|
||||
b= RG.radfactor*pow(col, RG.igamma);
|
||||
}
|
||||
|
||||
if(b>255) b=255;
|
||||
return b;
|
||||
}
|
||||
|
||||
void make_node_display()
|
||||
{
|
||||
RNode *rn, **el;
|
||||
int a;
|
||||
char *charcol;
|
||||
|
||||
RG.igamma= 1.0/RG.gamma;
|
||||
RG.radfactor= RG.radfac*pow(64*64, RG.igamma);
|
||||
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
rn= *el;
|
||||
charcol= (char *)&( rn->col );
|
||||
|
||||
charcol[3]= calculatecolor(rn->totrad[0]);
|
||||
charcol[2]= calculatecolor(rn->totrad[1]);
|
||||
charcol[1]= calculatecolor(rn->totrad[2]);
|
||||
|
||||
/* gouraudcolor */
|
||||
*(rn->v1+3)= 0;
|
||||
*(rn->v2+3)= 0;
|
||||
*(rn->v3+3)= 0;
|
||||
if(rn->v4) *(rn->v4+3)= 0;
|
||||
}
|
||||
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
rn= *el;
|
||||
addaccuweight( (char *)&(rn->col), (char *)(rn->v1+3), 16 );
|
||||
addaccuweight( (char *)&(rn->col), (char *)(rn->v2+3), 16 );
|
||||
addaccuweight( (char *)&(rn->col), (char *)(rn->v3+3), 16 );
|
||||
if(rn->v4) addaccuweight( (char *)&(rn->col), (char *)(rn->v4+3), 16 );
|
||||
}
|
||||
}
|
||||
|
||||
void drawnodeWire(RNode *rn)
|
||||
{
|
||||
|
||||
if(rn->down1) {
|
||||
drawnodeWire(rn->down1);
|
||||
drawnodeWire(rn->down2);
|
||||
}
|
||||
else {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv(rn->v1);
|
||||
glVertex3fv(rn->v2);
|
||||
glVertex3fv(rn->v3);
|
||||
if(rn->type==4) glVertex3fv(rn->v4);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void drawsingnodeWire(RNode *rn)
|
||||
{
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv(rn->v1);
|
||||
glVertex3fv(rn->v2);
|
||||
glVertex3fv(rn->v3);
|
||||
if(rn->type==4) glVertex3fv(rn->v4);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void drawnodeSolid(RNode *rn)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if(rn->down1) {
|
||||
drawnodeSolid(rn->down1);
|
||||
drawnodeSolid(rn->down2);
|
||||
}
|
||||
else {
|
||||
cp= (char *)&rn->col;
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex3fv(rn->v1);
|
||||
glVertex3fv(rn->v2);
|
||||
glVertex3fv(rn->v3);
|
||||
if(rn->type==4) glVertex3fv(rn->v4);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void drawnodeGour(RNode *rn)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if(rn->down1) {
|
||||
drawnodeGour(rn->down1);
|
||||
drawnodeGour(rn->down2);
|
||||
}
|
||||
else {
|
||||
glBegin(GL_POLYGON);
|
||||
cp= (char *)(rn->v1+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(rn->v1);
|
||||
|
||||
cp= (char *)(rn->v2+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(rn->v2);
|
||||
|
||||
cp= (char *)(rn->v3+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(rn->v3);
|
||||
|
||||
if(rn->type==4) {
|
||||
cp= (char *)(rn->v4+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(rn->v4);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void drawpatch_ext(RPatch *patch, unsigned int col)
|
||||
{
|
||||
ScrArea *sa, *oldsa;
|
||||
|
||||
glDrawBuffer(GL_FRONT);
|
||||
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
||||
|
||||
cpack(col);
|
||||
|
||||
oldsa= curarea;
|
||||
|
||||
sa= G.curscreen->areabase.first;
|
||||
while(sa) {
|
||||
if (sa->spacetype==SPACE_VIEW3D) {
|
||||
/* hier mywinget() gebruiken: anders wordt in header getekend */
|
||||
if(sa->win != mywinget()) areawinset(sa->win);
|
||||
drawnodeWire(patch->first);
|
||||
}
|
||||
sa= sa->next;
|
||||
}
|
||||
|
||||
if(oldsa && oldsa!=curarea) areawinset(oldsa->win);
|
||||
|
||||
glDrawBuffer(GL_BACK);
|
||||
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void drawnode_ext(RNode *rn, unsigned int col)
|
||||
{
|
||||
|
||||
glDrawBuffer(GL_FRONT);
|
||||
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
||||
|
||||
cpack(col);
|
||||
|
||||
drawnodeWire(rn);
|
||||
|
||||
glDrawBuffer(GL_BACK);
|
||||
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void drawOverflowElem()
|
||||
{
|
||||
RNode **el, *rn;
|
||||
float *fp;
|
||||
int a;
|
||||
|
||||
glDrawBuffer(GL_FRONT);
|
||||
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
||||
|
||||
cpack(0xFF9900);
|
||||
|
||||
el= RG.elem;
|
||||
fp= RG.formfactors;
|
||||
for(a=0; a<RG.totelem; a++, el++, fp++) {
|
||||
if(*fp>1.0) {
|
||||
rn= *el;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv( rn->v1);
|
||||
glVertex3fv( rn->v2);
|
||||
glVertex3fv( rn->v3);
|
||||
if(rn->type==4) glVertex3fv( rn->v4);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
glDrawBuffer(GL_BACK);
|
||||
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void drawfaceGour(Face *face)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
cp= (char *)(face->v1+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(face->v1);
|
||||
|
||||
cp= (char *)(face->v2+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(face->v2);
|
||||
|
||||
cp= (char *)(face->v3+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(face->v3);
|
||||
|
||||
if(face->v4) {
|
||||
cp= (char *)(face->v4+3);
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(face->v4);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
void drawfaceSolid(Face *face)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
cp= (char *)&face->col;
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex3fv(face->v1);
|
||||
glVertex3fv(face->v2);
|
||||
glVertex3fv(face->v3);
|
||||
if(face->v4) {
|
||||
glVertex3fv(face->v4);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
void drawfaceWire(Face *face)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
cp= (char *)&face->col;
|
||||
glColor3ub(cp[3], cp[2], cp[1]);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv(face->v1);
|
||||
glVertex3fv(face->v2);
|
||||
glVertex3fv(face->v3);
|
||||
if(face->v4) {
|
||||
glVertex3fv(face->v4);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
void drawsquare(float *cent, float size, short cox, short coy)
|
||||
{
|
||||
float vec[3];
|
||||
|
||||
vec[0]= cent[0];
|
||||
vec[1]= cent[1];
|
||||
vec[2]= cent[2];
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
vec[cox]+= .5*size;
|
||||
vec[coy]+= .5*size;
|
||||
glVertex3fv(vec);
|
||||
vec[coy]-= size;
|
||||
glVertex3fv(vec);
|
||||
vec[cox]-= size;
|
||||
glVertex3fv(vec);
|
||||
vec[coy]+= size;
|
||||
glVertex3fv(vec);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void drawlimits()
|
||||
{
|
||||
/* centreer rond cent */
|
||||
short cox=0, coy=1;
|
||||
|
||||
if((RG.flag & 3)==2) coy= 2;
|
||||
if((RG.flag & 3)==3) {
|
||||
cox= 1;
|
||||
coy= 2;
|
||||
}
|
||||
|
||||
cpack(0);
|
||||
drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy);
|
||||
drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy);
|
||||
|
||||
drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy);
|
||||
drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy);
|
||||
|
||||
cpack(0xFFFFFF);
|
||||
drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy);
|
||||
drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy);
|
||||
cpack(0xFFFF00);
|
||||
drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy);
|
||||
drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy);
|
||||
|
||||
}
|
||||
|
||||
void setcolNode(RNode *rn, unsigned int *col)
|
||||
{
|
||||
|
||||
if(rn->down1) {
|
||||
setcolNode(rn->down1, col);
|
||||
setcolNode(rn->down2, col);
|
||||
}
|
||||
rn->col= *col;
|
||||
|
||||
*((unsigned int *)rn->v1+3)= *col;
|
||||
*((unsigned int *)rn->v2+3)= *col;
|
||||
*((unsigned int *)rn->v3+3)= *col;
|
||||
if(rn->v4) *((unsigned int *)rn->v4+3)= *col;
|
||||
}
|
||||
|
||||
void pseudoAmb()
|
||||
{
|
||||
RPatch *rp;
|
||||
float fac;
|
||||
char col[4];
|
||||
|
||||
/* zet pseudo ambient kleuren in de nodes */
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
|
||||
if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) {
|
||||
col[1]= col[2]= col[3]= 255;
|
||||
}
|
||||
else {
|
||||
fac= rp->norm[0]+ rp->norm[1]+ rp->norm[2];
|
||||
fac= 225.0*(3+fac)/6.0;
|
||||
|
||||
col[3]= fac*rp->ref[0];
|
||||
col[2]= fac*rp->ref[1];
|
||||
col[1]= fac*rp->ref[2];
|
||||
}
|
||||
|
||||
setcolNode(rp->first, (unsigned int *)col);
|
||||
|
||||
rp= rp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void RAD_drawall(int depth_is_on)
|
||||
{
|
||||
/* maakt afbeelding van elements of van faces */
|
||||
Face *face = NULL;
|
||||
RNode **el;
|
||||
RPatch *rp;
|
||||
int a;
|
||||
|
||||
if(!depth_is_on) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
if(RG.totface) {
|
||||
if(RG.drawtype==DTGOUR) {
|
||||
glShadeModel(GL_SMOOTH);
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
|
||||
drawfaceGour(face);
|
||||
}
|
||||
}
|
||||
else if(RG.drawtype==DTSOLID) {
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
|
||||
drawfaceSolid(face);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!(get_qual()&LR_SHIFTKEY)) {
|
||||
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
|
||||
drawfaceWire(face);
|
||||
}
|
||||
}
|
||||
else {
|
||||
cpack(0);
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
drawsingnodeWire(rp->first);
|
||||
rp= rp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
el= RG.elem;
|
||||
if(RG.drawtype==DTGOUR) {
|
||||
glShadeModel(GL_SMOOTH);
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
drawnodeGour(*el);
|
||||
}
|
||||
}
|
||||
else if(RG.drawtype==DTSOLID) {
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
drawnodeSolid(*el);
|
||||
}
|
||||
}
|
||||
else {
|
||||
cpack(0);
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
drawnodeWire(*el);
|
||||
}
|
||||
}
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
if(RG.totpatch) {
|
||||
if(RG.flag & 3) {
|
||||
if(depth_is_on) glDisable(GL_DEPTH_TEST);
|
||||
drawlimits();
|
||||
if(depth_is_on) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
if(!depth_is_on) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void rad_forcedraw()
|
||||
{
|
||||
ScrArea *sa, *oldsa;
|
||||
|
||||
oldsa= curarea;
|
||||
|
||||
sa= G.curscreen->areabase.first;
|
||||
while(sa) {
|
||||
if (sa->spacetype==SPACE_VIEW3D) {
|
||||
/* hier mywinget() gebruiken: anders wordt in header getekend */
|
||||
if(sa->win != mywinget()) areawinset(sa->win);
|
||||
scrarea_do_windraw(sa);
|
||||
}
|
||||
sa= sa->next;
|
||||
}
|
||||
screen_swapbuffers();
|
||||
|
||||
if(oldsa && oldsa!=curarea) areawinset(oldsa->win);
|
||||
}
|
||||
|
956
source/blender/radiosity/intern/source/radfactors.c
Normal file
956
source/blender/radiosity/intern/source/radfactors.c
Normal file
@@ -0,0 +1,956 @@
|
||||
/* ***************************************
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
|
||||
|
||||
|
||||
formfactors.c nov/dec 1992
|
||||
|
||||
$Id$
|
||||
|
||||
*************************************** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "BIF_screen.h"
|
||||
|
||||
#include "radio.h"
|
||||
#include "render.h" /* for `RE_zbufferall_radio and RE_zbufferall_radio */
|
||||
#include "blendertimer.h" /* timer functions */
|
||||
|
||||
/* locals */
|
||||
void rad_setmatrices(RadView *vw);
|
||||
void clearsubflagelem(RNode *rn);
|
||||
void setsubflagelem(RNode *rn);
|
||||
|
||||
RadView hemitop, hemiside;
|
||||
|
||||
float calcStokefactor(RPatch *shoot, RPatch *rp, RNode *rn, float *area)
|
||||
{
|
||||
float tvec[3], fac;
|
||||
float vec[4][3]; /* vectoren van shootcent naar vertices rp */
|
||||
float cross[4][3]; /* uitprodukten hiervan */
|
||||
float rad[4]; /* hoeken tussen vecs */
|
||||
|
||||
/* test op richting */
|
||||
VecSubf(tvec, shoot->cent, rp->cent);
|
||||
if( tvec[0]*shoot->norm[0]+ tvec[1]*shoot->norm[1]+ tvec[2]*shoot->norm[2]>0.0)
|
||||
return 0.0;
|
||||
|
||||
if(rp->type==4) {
|
||||
|
||||
/* hoekvectors */
|
||||
VecSubf(vec[0], shoot->cent, rn->v1);
|
||||
VecSubf(vec[1], shoot->cent, rn->v2);
|
||||
VecSubf(vec[2], shoot->cent, rn->v3);
|
||||
VecSubf(vec[3], shoot->cent, rn->v4);
|
||||
|
||||
Normalise(vec[0]);
|
||||
Normalise(vec[1]);
|
||||
Normalise(vec[2]);
|
||||
Normalise(vec[3]);
|
||||
|
||||
/* uitprod */
|
||||
Crossf(cross[0], vec[0], vec[1]);
|
||||
Crossf(cross[1], vec[1], vec[2]);
|
||||
Crossf(cross[2], vec[2], vec[3]);
|
||||
Crossf(cross[3], vec[3], vec[0]);
|
||||
Normalise(cross[0]);
|
||||
Normalise(cross[1]);
|
||||
Normalise(cross[2]);
|
||||
Normalise(cross[3]);
|
||||
|
||||
/* hoeken */
|
||||
rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2];
|
||||
rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2];
|
||||
rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2];
|
||||
rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2];
|
||||
|
||||
rad[0]= acos(rad[0]);
|
||||
rad[1]= acos(rad[1]);
|
||||
rad[2]= acos(rad[2]);
|
||||
rad[3]= acos(rad[3]);
|
||||
|
||||
/* Stoke formule */
|
||||
VecMulf(cross[0], rad[0]);
|
||||
VecMulf(cross[1], rad[1]);
|
||||
VecMulf(cross[2], rad[2]);
|
||||
VecMulf(cross[3], rad[3]);
|
||||
|
||||
VECCOPY(tvec, shoot->norm);
|
||||
fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2];
|
||||
fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2];
|
||||
fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2];
|
||||
fac+= tvec[0]*cross[3][0]+ tvec[1]*cross[3][1]+ tvec[2]*cross[3][2];
|
||||
}
|
||||
else {
|
||||
/* hoekvectors */
|
||||
VecSubf(vec[0], shoot->cent, rn->v1);
|
||||
VecSubf(vec[1], shoot->cent, rn->v2);
|
||||
VecSubf(vec[2], shoot->cent, rn->v3);
|
||||
|
||||
Normalise(vec[0]);
|
||||
Normalise(vec[1]);
|
||||
Normalise(vec[2]);
|
||||
|
||||
/* uitprod */
|
||||
Crossf(cross[0], vec[0], vec[1]);
|
||||
Crossf(cross[1], vec[1], vec[2]);
|
||||
Crossf(cross[2], vec[2], vec[0]);
|
||||
Normalise(cross[0]);
|
||||
Normalise(cross[1]);
|
||||
Normalise(cross[2]);
|
||||
|
||||
/* hoeken */
|
||||
rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2];
|
||||
rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2];
|
||||
rad[2]= vec[2][0]*vec[0][0]+ vec[2][1]*vec[0][1]+ vec[2][2]*vec[0][2];
|
||||
|
||||
rad[0]= acos(rad[0]);
|
||||
rad[1]= acos(rad[1]);
|
||||
rad[2]= acos(rad[2]);
|
||||
|
||||
/* Stoke formule */
|
||||
VecMulf(cross[0], rad[0]);
|
||||
VecMulf(cross[1], rad[1]);
|
||||
VecMulf(cross[2], rad[2]);
|
||||
|
||||
VECCOPY(tvec, shoot->norm);
|
||||
fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2];
|
||||
fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2];
|
||||
fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2];
|
||||
}
|
||||
|
||||
*area= -fac/(2.0*PI);
|
||||
return (*area * (shoot->area/rn->area));
|
||||
}
|
||||
|
||||
|
||||
void calcTopfactors()
|
||||
{
|
||||
float xsq , ysq, xysq;
|
||||
float n;
|
||||
float *fp;
|
||||
int a, b, hres;
|
||||
|
||||
fp = RG.topfactors;
|
||||
hres= RG.hemires/2;
|
||||
n= hres;
|
||||
|
||||
for (a=0; a<hres; a++) {
|
||||
|
||||
ysq= (n- ((float)a+0.5))/n;
|
||||
ysq*= ysq;
|
||||
|
||||
for ( b=0 ; b<hres ; b++ ) {
|
||||
|
||||
xsq= ( n-((float)b+ 0.5) )/n;
|
||||
xsq*= xsq;
|
||||
xysq= xsq+ ysq+ 1.0 ;
|
||||
xysq*= xysq;
|
||||
|
||||
*fp++ = 1.0/(xysq* PI* n*n);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void calcSidefactors()
|
||||
{
|
||||
float xsq , ysq, xysq;
|
||||
float n, y;
|
||||
float *fp;
|
||||
int a, b, hres;
|
||||
|
||||
fp = RG.sidefactors;
|
||||
hres= RG.hemires/2;
|
||||
n= hres;
|
||||
|
||||
for (a=0; a<hres; a++) {
|
||||
|
||||
y= (n- ((float)a+0.5))/n;
|
||||
ysq= y*y;
|
||||
|
||||
for ( b=0 ; b<hres ; b++ ) {
|
||||
|
||||
xsq= ( n-((float)b+ 0.5) )/n;
|
||||
xsq*= xsq;
|
||||
xysq= xsq+ ysq+ 1.0 ;
|
||||
xysq*= xysq;
|
||||
|
||||
*fp++ = y/(xysq* PI* n*n);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void initradiosity()
|
||||
{
|
||||
/* alloceert en maakt LUTs voor top/side factors */
|
||||
/* alloceert en maakt index array */
|
||||
int a, hres2;
|
||||
|
||||
if(RG.topfactors) MEM_freeN(RG.topfactors);
|
||||
if(RG.sidefactors) MEM_freeN(RG.sidefactors);
|
||||
if(RG.index) MEM_freeN(RG.index);
|
||||
|
||||
RG.topfactors= MEM_callocN(RG.hemires*RG.hemires, "initradiosity");
|
||||
calcTopfactors();
|
||||
RG.sidefactors= MEM_callocN(RG.hemires*RG.hemires, "initradiosity1");
|
||||
calcSidefactors();
|
||||
|
||||
RG.index= MEM_callocN(4*RG.hemires, "initradiosity3");
|
||||
hres2= RG.hemires/2;
|
||||
for(a=0; a<RG.hemires; a++) {
|
||||
RG.index[a]= a<hres2 ? a: (hres2-1-( a % hres2 ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rad_make_hocos(RadView *vw)
|
||||
{
|
||||
/* float hoco[4]; */
|
||||
/* int a; */
|
||||
|
||||
/* for(a=0; a< R.totvert;a++) { */
|
||||
/* projectvert(vec, ver->ho); */
|
||||
/* ver->clip = testclip(ver->ho); */
|
||||
/* */
|
||||
/* } */
|
||||
}
|
||||
|
||||
void rad_setmatrices(RadView *vw) /* voor hemi's */
|
||||
{
|
||||
float up1[3], len, twist;
|
||||
|
||||
i_lookat(vw->cam[0], vw->cam[1], vw->cam[2], vw->tar[0], vw->tar[1], vw->tar[2], 0, vw->viewmat);
|
||||
up1[0] = vw->viewmat[0][0]*vw->up[0] + vw->viewmat[1][0]*vw->up[1] + vw->viewmat[2][0]*vw->up[2];
|
||||
up1[1] = vw->viewmat[0][1]*vw->up[0] + vw->viewmat[1][1]*vw->up[1] + vw->viewmat[2][1]*vw->up[2];
|
||||
up1[2] = vw->viewmat[0][2]*vw->up[0] + vw->viewmat[1][2]*vw->up[1] + vw->viewmat[2][2]*vw->up[2];
|
||||
|
||||
len= up1[0]*up1[0]+up1[1]*up1[1];
|
||||
if(len>0.0) {
|
||||
twist= -atan2(up1[0], up1[1]);
|
||||
}
|
||||
else twist= 0.0;
|
||||
|
||||
i_lookat(vw->cam[0], vw->cam[1], vw->cam[2], vw->tar[0], vw->tar[1], vw->tar[2], (180.0*twist/M_PI), vw->viewmat);
|
||||
|
||||
/* window matrix was set in inithemiwindows */
|
||||
|
||||
}
|
||||
|
||||
|
||||
void hemizbuf(RadView *vw)
|
||||
{
|
||||
float *factors;
|
||||
unsigned int *rz;
|
||||
int a, b, inda, hres;
|
||||
|
||||
rad_setmatrices(vw);
|
||||
RE_zbufferall_radio(vw, RG.elem, RG.totelem);
|
||||
|
||||
/* factors tellen */
|
||||
if(vw->recty==vw->rectx) factors= RG.topfactors;
|
||||
else factors= RG.sidefactors;
|
||||
hres= RG.hemires/2;
|
||||
|
||||
rz= vw->rect;
|
||||
for(a=0; a<vw->recty; a++) {
|
||||
inda= hres*RG.index[a];
|
||||
for(b=0; b<vw->rectx; b++, rz++) {
|
||||
if(*rz<RG.totelem) {
|
||||
RG.formfactors[*rz]+= factors[inda+RG.index[b]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int makeformfactors(RPatch *shoot)
|
||||
{
|
||||
RNode **re;
|
||||
float len, vec[3], up[3], side[3], tar[5][3], *fp;
|
||||
int a, overfl;
|
||||
|
||||
if(RG.totelem==0) return 0;
|
||||
|
||||
memset(RG.formfactors, 0, 4*RG.totelem);
|
||||
|
||||
/* set up hemiview */
|
||||
/* first: random upvector */
|
||||
do {
|
||||
vec[0]= (float)BLI_drand();
|
||||
vec[1]= (float)BLI_drand();
|
||||
vec[2]= (float)BLI_drand();
|
||||
Crossf(up, shoot->norm, vec);
|
||||
len= Normalise(up);
|
||||
} while(len==0.0 || len>1.0);
|
||||
|
||||
VECCOPY(hemitop.up, up);
|
||||
VECCOPY(hemiside.up, shoot->norm);
|
||||
|
||||
Crossf(side, shoot->norm, up);
|
||||
|
||||
/* five targets */
|
||||
VecAddf(tar[0], shoot->cent, shoot->norm);
|
||||
VecAddf(tar[1], shoot->cent, up);
|
||||
VecSubf(tar[2], shoot->cent, up);
|
||||
VecAddf(tar[3], shoot->cent, side);
|
||||
VecSubf(tar[4], shoot->cent, side);
|
||||
|
||||
/* camera */
|
||||
VECCOPY(hemiside.cam, shoot->cent);
|
||||
VECCOPY(hemitop.cam, shoot->cent);
|
||||
|
||||
/* do it! */
|
||||
VECCOPY(hemitop.tar, tar[0]);
|
||||
hemizbuf(&hemitop);
|
||||
|
||||
for(a=1; a<5; a++) {
|
||||
VECCOPY(hemiside.tar, tar[a]);
|
||||
hemizbuf(&hemiside);
|
||||
}
|
||||
|
||||
/* convert factors to real radiosity */
|
||||
re= RG.elem;
|
||||
fp= RG.formfactors;
|
||||
|
||||
overfl= 0;
|
||||
for(a= RG.totelem; a>0; a--, re++, fp++) {
|
||||
|
||||
if(*fp!=0.0) {
|
||||
|
||||
*fp *= shoot->area/(*re)->area;
|
||||
|
||||
if(*fp>1.0) {
|
||||
overfl= 1;
|
||||
*fp= 1.0001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(overfl) {
|
||||
/*
|
||||
drawOverflowElem();
|
||||
while(get_mbut()&L_MOUSE==0) {
|
||||
if(get_mbut()&M_MOUSE) {
|
||||
viewmove();
|
||||
drawpatch_ext(shoot,0xFF77FF);
|
||||
drawOverflowElem();
|
||||
}
|
||||
}
|
||||
*/
|
||||
if(shoot->first->down1) {
|
||||
splitpatch(shoot);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void applyformfactors(RPatch *shoot)
|
||||
{
|
||||
RPatch *rp;
|
||||
RNode **el, *rn;
|
||||
float *fp, *ref, unr, ung, unb, r, g, b, w;
|
||||
int a;
|
||||
|
||||
unr= shoot->unshot[0];
|
||||
ung= shoot->unshot[1];
|
||||
unb= shoot->unshot[2];
|
||||
|
||||
fp= RG.formfactors;
|
||||
el= RG.elem;
|
||||
for(a=0; a<RG.totelem; a++, el++, fp++) {
|
||||
rn= *el;
|
||||
if(*fp!= 0.0) {
|
||||
rp= rn->par;
|
||||
ref= rp->ref;
|
||||
|
||||
r= (*fp)*unr*ref[0];
|
||||
g= (*fp)*ung*ref[1];
|
||||
b= (*fp)*unb*ref[2];
|
||||
|
||||
w= rn->area/rp->area;
|
||||
rn->totrad[0]+= r;
|
||||
rn->totrad[1]+= g;
|
||||
rn->totrad[2]+= b;
|
||||
|
||||
rp->unshot[0]+= w*r;
|
||||
rp->unshot[1]+= w*g;
|
||||
rp->unshot[2]+= w*b;
|
||||
}
|
||||
}
|
||||
|
||||
shoot->unshot[0]= shoot->unshot[1]= shoot->unshot[2]= 0.0;
|
||||
}
|
||||
|
||||
RPatch *findshootpatch()
|
||||
{
|
||||
RPatch *rp, *shoot;
|
||||
float energy, maxenergy;
|
||||
|
||||
shoot= 0;
|
||||
maxenergy= 0.0;
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
energy= rp->unshot[0]*rp->area;
|
||||
energy+= rp->unshot[1]*rp->area;
|
||||
energy+= rp->unshot[2]*rp->area;
|
||||
|
||||
if(energy>maxenergy) {
|
||||
shoot= rp;
|
||||
maxenergy= energy;
|
||||
}
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
if(shoot) {
|
||||
maxenergy/= RG.totenergy;
|
||||
if(maxenergy<RG.convergence) return 0;
|
||||
}
|
||||
|
||||
return shoot;
|
||||
}
|
||||
|
||||
void setnodeflags(RNode *rn, int flag, int set)
|
||||
{
|
||||
|
||||
if(rn->down1) {
|
||||
setnodeflags(rn->down1, flag, set);
|
||||
setnodeflags(rn->down2, flag, set);
|
||||
}
|
||||
else {
|
||||
if(set) rn->f |= flag;
|
||||
else rn->f &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
void backface_test(RPatch *shoot)
|
||||
{
|
||||
RPatch *rp;
|
||||
float tvec[3];
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
if(rp!=shoot) {
|
||||
|
||||
VecSubf(tvec, shoot->cent, rp->cent);
|
||||
if( tvec[0]*shoot->norm[0]+ tvec[1]*shoot->norm[1]+ tvec[2]*shoot->norm[2]>0.0) {
|
||||
setnodeflags(rp->first, RAD_BACKFACE, 1);
|
||||
}
|
||||
}
|
||||
rp= rp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_backface_test()
|
||||
{
|
||||
RNode **re;
|
||||
int a;
|
||||
|
||||
re= RG.elem;
|
||||
for(a= RG.totelem-1; a>=0; a--, re++) {
|
||||
(*re)->f &= ~RAD_BACKFACE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rad_init_energy()
|
||||
{
|
||||
/* call before shooting */
|
||||
/* keep patches and elements, clear all data */
|
||||
RNode **el, *rn;
|
||||
RPatch *rp;
|
||||
int a;
|
||||
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
rn= *el;
|
||||
VECCOPY(rn->totrad, rn->par->emit);
|
||||
}
|
||||
|
||||
RG.totenergy= 0.0;
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
VECCOPY(rp->unshot, rp->emit);
|
||||
|
||||
RG.totenergy+= rp->unshot[0]*rp->area;
|
||||
RG.totenergy+= rp->unshot[1]*rp->area;
|
||||
RG.totenergy+= rp->unshot[2]*rp->area;
|
||||
|
||||
rp->f= 0;
|
||||
|
||||
rp= rp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void progressiverad()
|
||||
{
|
||||
RPatch *shoot;
|
||||
int it= 0;
|
||||
|
||||
rad_printstatus();
|
||||
rad_init_energy();
|
||||
|
||||
shoot=findshootpatch();
|
||||
|
||||
while( shoot ) {
|
||||
|
||||
setnodeflags(shoot->first, RAD_SHOOT, 1);
|
||||
|
||||
backface_test(shoot);
|
||||
|
||||
drawpatch_ext(shoot, 0x88FF00);
|
||||
|
||||
if( makeformfactors(shoot) ) {
|
||||
|
||||
applyformfactors(shoot);
|
||||
|
||||
it++;
|
||||
set_timecursor(it);
|
||||
if( (it & 3)==1 ) {
|
||||
make_node_display();
|
||||
rad_forcedraw();
|
||||
}
|
||||
setnodeflags(shoot->first, RAD_SHOOT, 0);
|
||||
}
|
||||
|
||||
clear_backface_test();
|
||||
|
||||
if(MISC_test_break()) break;
|
||||
if(RG.maxiter && RG.maxiter<=it) break;
|
||||
|
||||
shoot=findshootpatch();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ************* subdivideshoot *********** */
|
||||
|
||||
void minmaxradelem(RNode *rn, float *min, float *max)
|
||||
{
|
||||
int c;
|
||||
|
||||
if(rn->down1) {
|
||||
minmaxradelem(rn->down1, min, max);
|
||||
minmaxradelem(rn->down2, min, max);
|
||||
}
|
||||
else {
|
||||
for(c=0; c<3; c++) {
|
||||
min[c]= MIN2(min[c], rn->totrad[c]);
|
||||
max[c]= MAX2(max[c], rn->totrad[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void minmaxradelemfilt(RNode *rn, float *min, float *max, float *errmin, float *errmax)
|
||||
{
|
||||
float col[3], area;
|
||||
int c;
|
||||
|
||||
if(rn->down1) {
|
||||
minmaxradelemfilt(rn->down1, min, max, errmin, errmax);
|
||||
minmaxradelemfilt(rn->down2, min, max, errmin, errmax);
|
||||
}
|
||||
else {
|
||||
VECCOPY(col, rn->totrad);
|
||||
|
||||
for(c=0; c<3; c++) {
|
||||
min[c]= MIN2(min[c], col[c]);
|
||||
max[c]= MAX2(max[c], col[c]);
|
||||
}
|
||||
|
||||
VecMulf(col, 2.0);
|
||||
area= 2.0;
|
||||
if(rn->ed1) {
|
||||
VecAddf(col, rn->ed1->totrad, col);
|
||||
area+= 1.0;
|
||||
}
|
||||
if(rn->ed2) {
|
||||
VecAddf(col, rn->ed2->totrad, col);
|
||||
area+= 1.0;
|
||||
}
|
||||
if(rn->ed3) {
|
||||
VecAddf(col, rn->ed3->totrad, col);
|
||||
area+= 1.0;
|
||||
}
|
||||
if(rn->ed4) {
|
||||
VecAddf(col, rn->ed4->totrad, col);
|
||||
area+= 1.0;
|
||||
}
|
||||
VecMulf(col, 1.0/area);
|
||||
|
||||
for(c=0; c<3; c++) {
|
||||
errmin[c]= MIN2(errmin[c], col[c]);
|
||||
errmax[c]= MAX2(errmax[c], col[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setsubflagelem(RNode *rn)
|
||||
{
|
||||
|
||||
if(rn->down1) {
|
||||
setsubflagelem(rn->down1);
|
||||
setsubflagelem(rn->down2);
|
||||
}
|
||||
else {
|
||||
rn->f |= RAD_SUBDIV;
|
||||
}
|
||||
}
|
||||
|
||||
void clearsubflagelem(RNode *rn)
|
||||
{
|
||||
|
||||
if(rn->down1) {
|
||||
setsubflagelem(rn->down1);
|
||||
setsubflagelem(rn->down2);
|
||||
}
|
||||
else {
|
||||
rn->f &= ~RAD_SUBDIV;
|
||||
}
|
||||
}
|
||||
|
||||
void subdivideshootElements(int it)
|
||||
{
|
||||
RPatch *rp, *shoot;
|
||||
RNode **el, *rn;
|
||||
float *fp, err, stoke, area, min[3], max[3], errmin[3], errmax[3];
|
||||
int a, b, c, d, e, f, contin;
|
||||
int maxlamp;
|
||||
|
||||
if(RG.maxsublamp==0) maxlamp= RG.totlamp;
|
||||
else maxlamp= RG.maxsublamp;
|
||||
|
||||
while(it) {
|
||||
rad_printstatus();
|
||||
rad_init_energy();
|
||||
it--;
|
||||
|
||||
for(a=0; a<maxlamp; a++) {
|
||||
shoot= findshootpatch();
|
||||
if(shoot==0) break;
|
||||
|
||||
set_timecursor(a);
|
||||
drawpatch_ext(shoot, 0x88FF00);
|
||||
|
||||
setnodeflags(shoot->first, RAD_SHOOT, 1);
|
||||
if( makeformfactors(shoot) ) {
|
||||
|
||||
fp= RG.formfactors;
|
||||
el= RG.elem;
|
||||
for(b=RG.totelem; b>0; b--, el++) {
|
||||
rn= *el;
|
||||
|
||||
if( (rn->f & RAD_SUBDIV)==0 && *fp!=0.0) {
|
||||
if(rn->par->emit[0]+rn->par->emit[1]+rn->par->emit[2]==0.0) {
|
||||
|
||||
stoke= calcStokefactor(shoot, rn->par, rn, &area);
|
||||
if(stoke!= 0.0) {
|
||||
|
||||
err= *fp/stoke;
|
||||
|
||||
/* area error */
|
||||
area*=(0.5*RG.hemires*RG.hemires);
|
||||
|
||||
if(area>35.0) {
|
||||
if(err<0.95 || err>1.05) {
|
||||
if(err>0.05) {
|
||||
rn->f |= RAD_SUBDIV;
|
||||
rn->par->f |= RAD_SUBDIV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fp++;
|
||||
|
||||
}
|
||||
|
||||
applyformfactors(shoot);
|
||||
|
||||
if( (a & 3)==1 ) {
|
||||
make_node_display();
|
||||
rad_forcedraw();
|
||||
}
|
||||
|
||||
setnodeflags(shoot->first, RAD_SHOOT, 0);
|
||||
}
|
||||
else a--;
|
||||
|
||||
if(MISC_test_break()) break;
|
||||
}
|
||||
|
||||
/* test op extreem weinig kleurverloop binnen patch met subdivflag */
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
|
||||
while(rp) {
|
||||
if(rp->f & RAD_SUBDIV) { /* rp heeft elems die moet gesubd */
|
||||
/* minstens 4 levels diep */
|
||||
rn= rp->first->down1;
|
||||
if(rn) {
|
||||
rn= rn->down1;
|
||||
if(rn) {
|
||||
rn= rn->down1;
|
||||
if(rn) rn= rn->down1;
|
||||
}
|
||||
}
|
||||
if(rn) {
|
||||
min[0]= min[1]= min[2]= 1.0e10;
|
||||
max[0]= max[1]= max[2]= -1.0e10;
|
||||
/* errmin en max zijn de gefilterde kleuren */
|
||||
errmin[0]= errmin[1]= errmin[2]= 1.0e10;
|
||||
errmax[0]= errmax[1]= errmax[2]= -1.0e10;
|
||||
minmaxradelemfilt(rp->first, min, max, errmin, errmax);
|
||||
|
||||
/* verschil tussen kleuren klein: toch maar niet subd */
|
||||
/* test ook voor de gefilterde: maar kritischer */
|
||||
|
||||
contin= 0;
|
||||
a= abs( calculatecolor(min[0])-calculatecolor(max[0]));
|
||||
b= abs( calculatecolor(errmin[0])-calculatecolor(errmax[0]));
|
||||
if(a<15 || b<7) {
|
||||
c= abs( calculatecolor(min[1])-calculatecolor(max[1]));
|
||||
d= abs( calculatecolor(errmin[1])-calculatecolor(errmax[1]));
|
||||
if(c<15 || d<7) {
|
||||
e= abs( calculatecolor(min[2])-calculatecolor(max[2]));
|
||||
f= abs( calculatecolor(errmin[2])-calculatecolor(errmax[2]));
|
||||
if(e<15 || f<7) {
|
||||
contin= 1;
|
||||
clearsubflagelem(rp->first);
|
||||
/* printf("%d %d %d %d %d %d\n", a, b, c, d, e, f); */
|
||||
}
|
||||
}
|
||||
}
|
||||
if(contin) {
|
||||
drawpatch_ext(rp, 0xFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
rp->f &= ~RAD_SUBDIV;
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
contin= 0;
|
||||
|
||||
el= RG.elem;
|
||||
for(b=RG.totelem; b>0; b--, el++) {
|
||||
rn= *el;
|
||||
if(rn->f & RAD_SUBDIV) {
|
||||
rn->f-= RAD_SUBDIV;
|
||||
subdivideNode(rn, 0);
|
||||
if(rn->down1) {
|
||||
subdivideNode(rn->down1, 0);
|
||||
subdivideNode(rn->down2, 0);
|
||||
contin= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
makeGlobalElemArray();
|
||||
|
||||
if(contin==0 || MISC_test_break()) break;
|
||||
}
|
||||
|
||||
make_node_display();
|
||||
}
|
||||
|
||||
void subdivideshootPatches(int it)
|
||||
{
|
||||
RPatch *rp, *shoot, *next;
|
||||
float *fp, err, stoke, area;
|
||||
int a, contin;
|
||||
int maxlamp;
|
||||
|
||||
if(RG.maxsublamp==0) maxlamp= RG.totlamp;
|
||||
else maxlamp= RG.maxsublamp;
|
||||
|
||||
while(it) {
|
||||
rad_printstatus();
|
||||
rad_init_energy();
|
||||
it--;
|
||||
|
||||
for(a=0; a<maxlamp; a++) {
|
||||
shoot= findshootpatch();
|
||||
if(shoot==0) break;
|
||||
|
||||
set_timecursor(a);
|
||||
drawpatch_ext(shoot, 0x88FF00);
|
||||
|
||||
setnodeflags(shoot->first, RAD_SHOOT, 1);
|
||||
|
||||
if( makeformfactors(shoot) ) {
|
||||
|
||||
fp= RG.formfactors;
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
if(*fp!=0.0 && rp!=shoot) {
|
||||
|
||||
stoke= calcStokefactor(shoot, rp, rp->first, &area);
|
||||
if(stoke!= 0.0) {
|
||||
if(area>.1) { /* ontvangt patch meer dan (ong)10% van energie? */
|
||||
rp->f= RAD_SUBDIV;
|
||||
}
|
||||
else {
|
||||
|
||||
err= *fp/stoke;
|
||||
|
||||
/* area error */
|
||||
area*=(0.5*RG.hemires*RG.hemires);
|
||||
|
||||
if(area>45.0) {
|
||||
if(err<0.95 || err>1.05) {
|
||||
if(err>0.05) {
|
||||
|
||||
rp->f= RAD_SUBDIV;
|
||||
|
||||
/* if(get_qual()&LR_SHIFTKEY);
|
||||
else {
|
||||
drawpatch_ext(rp, 0xFF77FF);
|
||||
|
||||
printf("Pa hemi %f stoke %f err %f area %f\n", *fp, stoke, err, area);
|
||||
|
||||
while(get_mbut()&L_MOUSE==0);
|
||||
while(get_mbut()&L_MOUSE);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fp++;
|
||||
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
applyformfactors(shoot);
|
||||
|
||||
if( (a & 3)==1 ) {
|
||||
make_node_display();
|
||||
rad_forcedraw();
|
||||
}
|
||||
|
||||
setnodeflags(shoot->first, RAD_SHOOT, 0);
|
||||
|
||||
if(MISC_test_break()) break;
|
||||
}
|
||||
else a--;
|
||||
|
||||
}
|
||||
|
||||
contin= 0;
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
next= rp->next;
|
||||
if(rp->f & RAD_SUBDIV) {
|
||||
if(rp->emit[0]+rp->emit[1]+rp->emit[2]==0.0) {
|
||||
contin= 1;
|
||||
subdivideNode(rp->first, 0);
|
||||
if(rp->first->down1) {
|
||||
subdivideNode(rp->first->down1, 0);
|
||||
subdivideNode(rp->first->down2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
rp= next;
|
||||
}
|
||||
|
||||
converttopatches();
|
||||
makeGlobalElemArray();
|
||||
|
||||
if(contin==0 || MISC_test_break()) break;
|
||||
}
|
||||
make_node_display();
|
||||
}
|
||||
|
||||
void inithemiwindows()
|
||||
{
|
||||
RadView *vw;
|
||||
|
||||
/* de hemiwindows */
|
||||
vw= &(hemitop);
|
||||
memset(vw, 0, sizeof(RadView));
|
||||
vw->rectx= RG.hemires;
|
||||
vw->recty= RG.hemires;
|
||||
vw->rectz= MEM_mallocN(4*vw->rectx*vw->recty, "initwindows");
|
||||
vw->rect= MEM_mallocN(4*vw->rectx*vw->recty, "initwindows");
|
||||
vw->mynear= RG.maxsize/2000.0;
|
||||
vw->myfar= 2.0*RG.maxsize;
|
||||
vw->wx1= -vw->mynear;
|
||||
vw->wx2= vw->mynear;
|
||||
vw->wy1= -vw->mynear;
|
||||
vw->wy2= vw->mynear;
|
||||
|
||||
i_window(vw->wx1, vw->wx2, vw->wy1, vw->wy2, vw->mynear, vw->myfar, vw->winmat);
|
||||
|
||||
hemiside= hemitop;
|
||||
|
||||
vw= &(hemiside);
|
||||
vw->recty/= 2;
|
||||
vw->wy1= vw->wy2;
|
||||
vw->wy2= 0.0;
|
||||
|
||||
i_window(vw->wx1, vw->wx2, vw->wy1, vw->wy2, vw->mynear, vw->myfar, vw->winmat);
|
||||
|
||||
}
|
||||
|
||||
void closehemiwindows()
|
||||
{
|
||||
|
||||
if(hemiside.rect) MEM_freeN(hemiside.rect);
|
||||
if(hemiside.rectz) MEM_freeN(hemiside.rectz);
|
||||
hemiside.rectz= 0;
|
||||
hemiside.rect= 0;
|
||||
hemitop.rectz= 0;
|
||||
hemitop.rect= 0;
|
||||
}
|
379
source/blender/radiosity/intern/source/radio.c
Normal file
379
source/blender/radiosity/intern/source/radio.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/* ***************************************
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
|
||||
|
||||
|
||||
radio.c nov/dec 1992
|
||||
may 1999
|
||||
|
||||
$Id$
|
||||
|
||||
- mainlus
|
||||
- toetsafhandeling
|
||||
|
||||
|
||||
- PREPROCES
|
||||
- collect meshes
|
||||
- spitconnected (alle vlakken met verschillende kleur en normaal)
|
||||
- setedgepointers (nodes wijzen naar buren)
|
||||
|
||||
- EDITING
|
||||
- min-max patch en min-max elementsize
|
||||
- ahv bovenstaande evt patches subdividen
|
||||
- lampsubdivide
|
||||
|
||||
- als er teveel lampen zijn voor de subdivide shooting:
|
||||
- tijdelijk patches samenvoegen
|
||||
- met de hand aangeven?
|
||||
|
||||
- SUBDIVIDE SHOOTING
|
||||
- behalve laatste shooting bepaalt dit patch-subdivide
|
||||
- als gesubdivide patches nog > 2*minsize : doorgaan
|
||||
- op eind zoveel mogelijk elements maken
|
||||
- ook onthouden of lamp (nog) subdivide veroorzaakt.
|
||||
|
||||
- REFINEMENT SHOOTING
|
||||
- testen op overflows (shootpatch subdividen)
|
||||
- testen op extreme kleur verlopen:
|
||||
- als nog kan: shootpatch subdividen
|
||||
- elements subdividen = overnieuw beginnen ?
|
||||
- ittereren stoppen nadat ?
|
||||
|
||||
- DEFINITIVE SHOOTING
|
||||
- user geeft aan hoeveel vlakken maximaal en itteratie lengte.
|
||||
- nodes omzetten naar minder geheugen-intensief formaat
|
||||
- element- nodes weer samenvoegen waarin niets gebeurt (faces)
|
||||
- elements subdividen waarin veel gebeurt
|
||||
|
||||
*************************************** */
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_radio_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "BIF_screen.h" /* curarea */
|
||||
#include "BIF_space.h" /* allqueue */
|
||||
|
||||
#include "radio.h"
|
||||
#include "mydevice.h"
|
||||
|
||||
/* locals? This one was already done in radio.h... */
|
||||
/* void rad_status_str(char *str); */
|
||||
|
||||
RadGlobal RG= {0, 0};
|
||||
|
||||
void freeAllRad()
|
||||
{
|
||||
Base *base;
|
||||
extern int Ntotvert, Ntotnode, Ntotpatch;
|
||||
|
||||
/* clear flag that disables drawing the meshes */
|
||||
if(G.scene) {
|
||||
base= (G.scene->base.first);
|
||||
while(base) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
base->flag &= ~OB_RADIO;
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
|
||||
free_fastAll(); /* verts, nodes, patches */
|
||||
RG.patchbase.first= RG.patchbase.last= 0;
|
||||
Ntotvert= Ntotnode= Ntotpatch= 0;
|
||||
|
||||
closehemiwindows(); /* not real windows anymore... */
|
||||
if(RG.elem) MEM_freeN(RG.elem);
|
||||
RG.elem= 0;
|
||||
if(RG.verts) MEM_freeN(RG.verts);
|
||||
RG.verts= 0;
|
||||
if(RG.topfactors) MEM_freeN(RG.topfactors);
|
||||
RG.topfactors= 0;
|
||||
if(RG.sidefactors) MEM_freeN(RG.sidefactors);
|
||||
RG.sidefactors= 0;
|
||||
if(RG.formfactors) MEM_freeN(RG.formfactors);
|
||||
RG.formfactors= 0;
|
||||
if(RG.index) MEM_freeN(RG.index);
|
||||
RG.index= 0;
|
||||
if(RG.facebase) {
|
||||
init_face_tab(); /* frees all tables */
|
||||
MEM_freeN(RG.facebase);
|
||||
RG.facebase= 0;
|
||||
}
|
||||
RG.totelem= RG.totpatch= RG.totvert= RG.totface= RG.totlamp= RG.totmat= 0;
|
||||
}
|
||||
|
||||
int rad_phase()
|
||||
{
|
||||
int flag= 0;
|
||||
|
||||
if(RG.totpatch) flag |= RAD_PHASE_PATCHES;
|
||||
if(RG.totface) flag |= RAD_PHASE_FACES;
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
void rad_status_str(char *str)
|
||||
{
|
||||
extern int totfastmem;
|
||||
int tot;
|
||||
char *phase;
|
||||
|
||||
tot= (RG.totface*sizeof(Face))/1024;
|
||||
tot+= totfastmem/1024;
|
||||
|
||||
if(RG.phase==RAD_SHOOTE) phase= "Phase: ELEMENT SUBD, ";
|
||||
else if(RG.phase==RAD_SHOOTP) phase= "Phase: PATCH SUBD, ";
|
||||
else if(RG.phase==RAD_SOLVE) phase= "Phase: SOLVE, ";
|
||||
else if(RG.totpatch==0) phase= "Phase: COLLECT MESHES ";
|
||||
else if(RG.totface) phase= "Phase: FINISHED, ";
|
||||
else phase= "Phase: INIT, ";
|
||||
|
||||
if(RG.totpatch==0) strcpy(str, phase);
|
||||
else sprintf(str, "%s TotPatch: %d TotElem: %d Emit: %d Faces %d Mem: %d k ", phase, RG.totpatch, RG.totelem, RG.totlamp, RG.totface, tot);
|
||||
|
||||
if(RG.phase==RAD_SOLVE) strcat(str, "(press ESC to stop)");
|
||||
}
|
||||
|
||||
void rad_printstatus()
|
||||
{
|
||||
/* actions always are started from a buttonswindow */
|
||||
scrarea_do_windraw(curarea);
|
||||
screen_swapbuffers();
|
||||
}
|
||||
|
||||
void rad_setlimits()
|
||||
{
|
||||
Radio *rad= G.scene->radio;
|
||||
float fac;
|
||||
|
||||
fac= 0.0005*rad->pama;
|
||||
RG.patchmax= RG.maxsize*fac;
|
||||
RG.patchmax*= RG.patchmax;
|
||||
fac= 0.0005*rad->pami;
|
||||
RG.patchmin= RG.maxsize*fac;
|
||||
RG.patchmin*= RG.patchmin;
|
||||
|
||||
fac= 0.0005*rad->elma;
|
||||
RG.elemmax= RG.maxsize*fac;
|
||||
RG.elemmax*= RG.elemmax;
|
||||
fac= 0.0005*rad->elmi;
|
||||
RG.elemmin= RG.maxsize*fac;
|
||||
RG.elemmin*= RG.elemmin;
|
||||
}
|
||||
|
||||
void set_radglobal()
|
||||
{
|
||||
/* always call before any action is performed */
|
||||
Radio *rad= G.scene->radio;
|
||||
|
||||
if(RG.radio==0) {
|
||||
/* firsttime and to be sure */
|
||||
memset(&RG, 0, sizeof(RadGlobal));
|
||||
}
|
||||
|
||||
if(rad==0) return;
|
||||
|
||||
if(rad != RG.radio) {
|
||||
if(RG.radio) freeAllRad();
|
||||
memset(&RG, 0, sizeof(RadGlobal));
|
||||
RG.radio= rad;
|
||||
}
|
||||
|
||||
RG.hemires= rad->hemires & 0xFFF0;
|
||||
RG.drawtype= rad->drawtype;
|
||||
RG.flag= rad->flag;
|
||||
RG.subshootp= rad->subshootp;
|
||||
RG.subshoote= rad->subshoote;
|
||||
RG.nodelim= rad->nodelim;
|
||||
RG.maxsublamp= rad->maxsublamp;
|
||||
RG.maxnode= 2*rad->maxnode; /* in button:max elem, subdividing! */
|
||||
RG.convergence= rad->convergence/1000.0;
|
||||
RG.radfac= rad->radfac;
|
||||
RG.gamma= rad->gamma;
|
||||
RG.maxiter= rad->maxiter;
|
||||
|
||||
rad_setlimits();
|
||||
}
|
||||
|
||||
/* called from buttons.c */
|
||||
void add_radio()
|
||||
{
|
||||
Radio *rad;
|
||||
|
||||
if(G.scene->radio) MEM_freeN(G.scene->radio);
|
||||
rad= G.scene->radio= MEM_callocN(sizeof(Radio), "radio");
|
||||
|
||||
rad->hemires= 300;
|
||||
rad->convergence= 0.1;
|
||||
rad->radfac= 30.0;
|
||||
rad->gamma= 2.0;
|
||||
rad->drawtype= DTSOLID;
|
||||
rad->subshootp= 1;
|
||||
rad->subshoote= 2;
|
||||
rad->maxsublamp= 0;
|
||||
|
||||
rad->pama= 500;
|
||||
rad->pami= 200;
|
||||
rad->elma= 100;
|
||||
rad->elmi= 20;
|
||||
rad->nodelim= 0;
|
||||
rad->maxnode= 10000;
|
||||
rad->flag= 2;
|
||||
set_radglobal();
|
||||
}
|
||||
|
||||
void delete_radio()
|
||||
{
|
||||
freeAllRad();
|
||||
if(G.scene->radio) MEM_freeN(G.scene->radio);
|
||||
G.scene->radio= 0;
|
||||
|
||||
RG.radio= 0;
|
||||
}
|
||||
|
||||
int rad_go(void) /* return 0 when user escapes */
|
||||
{
|
||||
double stime= PIL_check_seconds_timer();
|
||||
int retval;
|
||||
/* firsttime moet vervangen worden door radphase? */
|
||||
|
||||
if(RG.totface) return 0;
|
||||
|
||||
G.afbreek= 0;
|
||||
|
||||
set_radglobal();
|
||||
initradiosity(); /* LUT's */
|
||||
inithemiwindows(); /* views */
|
||||
|
||||
maxsizePatches();
|
||||
|
||||
setnodelimit(RG.patchmin);
|
||||
RG.phase= RAD_SHOOTP;
|
||||
subdivideshootPatches(RG.subshootp);
|
||||
|
||||
setnodelimit(RG.elemmin);
|
||||
RG.phase= RAD_SHOOTE;
|
||||
subdivideshootElements(RG.subshoote);
|
||||
|
||||
setnodelimit(RG.patchmin);
|
||||
subdividelamps();
|
||||
|
||||
setnodelimit(RG.elemmin);
|
||||
|
||||
RG.phase= RAD_SOLVE;
|
||||
subdiv_elements();
|
||||
|
||||
progressiverad();
|
||||
|
||||
removeEqualNodes(RG.nodelim);
|
||||
|
||||
make_face_tab(); /* nu geankerd */
|
||||
|
||||
closehemiwindows();
|
||||
RG.phase= 0;
|
||||
|
||||
stime= PIL_check_seconds_timer()-stime;
|
||||
printf("Radiosity solving time: %dms\n", (int) (stime*1000));
|
||||
|
||||
if(G.afbreek==1) retval= 1;
|
||||
else retval= 0;
|
||||
|
||||
G.afbreek= 0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void rad_subdivshootpatch()
|
||||
{
|
||||
|
||||
if(RG.totface) return;
|
||||
|
||||
G.afbreek= 0;
|
||||
|
||||
set_radglobal();
|
||||
initradiosity(); /* LUT's */
|
||||
inithemiwindows(); /* views */
|
||||
|
||||
subdivideshootPatches(1);
|
||||
|
||||
removeEqualNodes(RG.nodelim);
|
||||
closehemiwindows();
|
||||
|
||||
allqueue(REDRAWVIEW3D, 1);
|
||||
}
|
||||
|
||||
void rad_subdivshootelem(void)
|
||||
{
|
||||
|
||||
if(RG.totface) return;
|
||||
|
||||
G.afbreek= 0;
|
||||
|
||||
set_radglobal();
|
||||
initradiosity(); /* LUT's */
|
||||
inithemiwindows(); /* views */
|
||||
|
||||
subdivideshootElements(1);
|
||||
|
||||
removeEqualNodes(RG.nodelim);
|
||||
closehemiwindows();
|
||||
|
||||
allqueue(REDRAWVIEW3D, 1);
|
||||
}
|
||||
|
||||
void rad_limit_subdivide()
|
||||
{
|
||||
|
||||
if(G.scene->radio==0) return;
|
||||
|
||||
set_radglobal();
|
||||
|
||||
if(RG.totpatch==0) {
|
||||
/* printf("exit: no relevant data\n"); */
|
||||
return;
|
||||
}
|
||||
|
||||
maxsizePatches();
|
||||
|
||||
init_face_tab(); /* free faces */
|
||||
}
|
1095
source/blender/radiosity/intern/source/radnode.c
Normal file
1095
source/blender/radiosity/intern/source/radnode.c
Normal file
File diff suppressed because it is too large
Load Diff
871
source/blender/radiosity/intern/source/radpostprocess.c
Normal file
871
source/blender/radiosity/intern/source/radpostprocess.c
Normal file
@@ -0,0 +1,871 @@
|
||||
/* ***************************************
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
|
||||
|
||||
|
||||
radpostprocess.c nov/dec 1992
|
||||
may 1999
|
||||
|
||||
- faces
|
||||
- filtering and node-limit
|
||||
- apply to meshes
|
||||
$Id$
|
||||
|
||||
*************************************** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_radio_types.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "BIF_screen.h" /* waitcursor */
|
||||
#include "BIF_editview.h" /* deselectall */
|
||||
|
||||
#include "BDR_editobject.h" /* delete_obj */
|
||||
|
||||
#include "radio.h"
|
||||
|
||||
/* locals? not. done in radio.h... */
|
||||
/* void rad_addmesh(void); */
|
||||
/* void rad_replacemesh(void); */
|
||||
|
||||
void addaccu(register char *z, register char *t)
|
||||
{
|
||||
register int div, mul;
|
||||
|
||||
mul= *t;
|
||||
div= mul+1;
|
||||
(*t)++;
|
||||
|
||||
t[1]= (mul*t[1]+z[1])/div;
|
||||
t[2]= (mul*t[2]+z[2])/div;
|
||||
t[3]= (mul*t[3]+z[3])/div;
|
||||
|
||||
}
|
||||
|
||||
void addaccuweight(register char *z, register char *t, int w)
|
||||
{
|
||||
register int div, mul;
|
||||
|
||||
if(w==0) w= 1;
|
||||
|
||||
mul= *t;
|
||||
div= mul+w;
|
||||
if(div>255) return;
|
||||
(*t)= div;
|
||||
|
||||
t[1]= (mul*t[1]+w*z[1])/div;
|
||||
t[2]= (mul*t[2]+w*z[2])/div;
|
||||
t[3]= (mul*t[3]+w*z[3])/div;
|
||||
|
||||
}
|
||||
|
||||
void triaweight(Face *face, int *w1, int *w2, int *w3)
|
||||
{
|
||||
float n1[3], n2[3], n3[3], temp;
|
||||
|
||||
n1[0]= face->v2[0]-face->v1[0];
|
||||
n1[1]= face->v2[1]-face->v1[1];
|
||||
n1[2]= face->v2[2]-face->v1[2];
|
||||
n2[0]= face->v3[0]-face->v2[0];
|
||||
n2[1]= face->v3[1]-face->v2[1];
|
||||
n2[2]= face->v3[2]-face->v2[2];
|
||||
n3[0]= face->v1[0]-face->v3[0];
|
||||
n3[1]= face->v1[1]-face->v3[1];
|
||||
n3[2]= face->v1[2]-face->v3[2];
|
||||
Normalise(n1);
|
||||
Normalise(n2);
|
||||
Normalise(n3);
|
||||
temp= 32.0/(PI);
|
||||
*w1= 0.5+temp*acos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
|
||||
*w2= 0.5+temp*acos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
|
||||
*w3= 0.5+temp*acos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void init_face_tab()
|
||||
{
|
||||
int a= 0;
|
||||
|
||||
if(RG.facebase==0) {
|
||||
RG.facebase= MEM_callocN(sizeof(void *)*RAD_MAXFACETAB, "init_face_tab");
|
||||
}
|
||||
for(a=0; a<RAD_MAXFACETAB; a++) {
|
||||
if(RG.facebase[a]==0) break;
|
||||
MEM_freeN(RG.facebase[a]);
|
||||
RG.facebase[a]= 0;
|
||||
}
|
||||
RG.totface= 0;
|
||||
}
|
||||
|
||||
Face *addface()
|
||||
{
|
||||
Face *face;
|
||||
int a;
|
||||
|
||||
if(RG.totface<0 || RG.totface>RAD_MAXFACETAB*1024 ) {
|
||||
printf("error in addface: %d\n", RG.totface);
|
||||
return 0;
|
||||
}
|
||||
a= RG.totface>>10;
|
||||
face= RG.facebase[a];
|
||||
if(face==0) {
|
||||
face= MEM_callocN(1024*sizeof(Face),"addface");
|
||||
RG.facebase[a]= face;
|
||||
}
|
||||
face+= (RG.totface & 1023);
|
||||
|
||||
RG.totface++;
|
||||
|
||||
return face;
|
||||
|
||||
}
|
||||
|
||||
void makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn)
|
||||
{
|
||||
Face *face;
|
||||
|
||||
face= addface();
|
||||
face->v1= v1;
|
||||
face->v2= v2;
|
||||
face->v3= v3;
|
||||
face->v4= v4;
|
||||
face->col= rn->col;
|
||||
face->matindex= rn->par->matindex;
|
||||
}
|
||||
|
||||
|
||||
void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag)
|
||||
{
|
||||
|
||||
switch(flag) {
|
||||
case 1:
|
||||
makeface(rn->v1, v1, rn->v4, 0, rn);
|
||||
makeface(v1, rn->v3, rn->v4, 0, rn);
|
||||
makeface(v1, rn->v2, rn->v3, 0, rn);
|
||||
break;
|
||||
case 2:
|
||||
makeface(rn->v2, v2, rn->v1, 0, rn);
|
||||
makeface(v2, rn->v4, rn->v1, 0, rn);
|
||||
makeface(v2, rn->v3, rn->v4, 0, rn);
|
||||
break;
|
||||
case 4:
|
||||
makeface(rn->v3, v3, rn->v2, 0, rn);
|
||||
makeface(v3, rn->v1, rn->v2, 0, rn);
|
||||
makeface(v3, rn->v4, rn->v1, 0, rn);
|
||||
break;
|
||||
case 8:
|
||||
makeface(rn->v4, v4, rn->v3, 0, rn);
|
||||
makeface(v4, rn->v2, rn->v3, 0, rn);
|
||||
makeface(v4, rn->v1, rn->v2, 0, rn);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
makeface(rn->v1, v1, rn->v4, 0, rn);
|
||||
makeface(v1, v2, rn->v4, 0, rn);
|
||||
makeface(v1, rn->v2, v2, 0, rn);
|
||||
makeface(v2, rn->v3, rn->v4, 0, rn);
|
||||
break;
|
||||
case 6:
|
||||
makeface(rn->v2, v2, rn->v1, 0, rn);
|
||||
makeface(v2, v3, rn->v1, 0, rn);
|
||||
makeface(v2, rn->v3, v3, 0, rn);
|
||||
makeface(v3, rn->v4, rn->v1, 0, rn);
|
||||
break;
|
||||
case 12:
|
||||
makeface(rn->v3, v3, rn->v2, 0, rn);
|
||||
makeface(v3, v4, rn->v2, 0, rn);
|
||||
makeface(v3, rn->v4, v4, 0, rn);
|
||||
makeface(v4, rn->v1, rn->v2, 0, rn);
|
||||
break;
|
||||
case 9:
|
||||
makeface(rn->v4, v4, rn->v3, 0, rn);
|
||||
makeface(v4, v1, rn->v3, 0, rn);
|
||||
makeface(v4, rn->v1, v1, 0, rn);
|
||||
makeface(v1, rn->v2, rn->v3, 0, rn);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
makeface(rn->v1, v1, v3, rn->v4, rn);
|
||||
makeface(v1, rn->v2, rn->v3, v3, rn);
|
||||
break;
|
||||
case 10:
|
||||
makeface(rn->v2, v2, v4, rn->v1, rn);
|
||||
makeface(v2, rn->v3, rn->v4, v4, rn);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
makeface(rn->v1, v1, v3, rn->v4, rn);
|
||||
makeface(v1, v2, v3, 0, rn);
|
||||
makeface(v1, rn->v2, v2, 0, rn);
|
||||
makeface(v2, rn->v3, v3, 0, rn);
|
||||
break;
|
||||
case 14:
|
||||
makeface(rn->v2, v2, v4, rn->v1, rn);
|
||||
makeface(v2, v3, v4, 0, rn);
|
||||
makeface(v2, rn->v3, v3, 0, rn);
|
||||
makeface(v3, rn->v4, v4, 0, rn);
|
||||
break;
|
||||
case 13:
|
||||
makeface(rn->v3, v3, v1, rn->v2, rn);
|
||||
makeface(v3, v4, v1, 0, rn);
|
||||
makeface(v3, rn->v4, v4, 0, rn);
|
||||
makeface(v4, rn->v1, v1, 0, rn);
|
||||
break;
|
||||
case 11:
|
||||
makeface(rn->v4, v4, v2, rn->v3, rn);
|
||||
makeface(v4, v1, v2, 0, rn);
|
||||
makeface(v4, rn->v1, v1, 0, rn);
|
||||
makeface(v1, rn->v2, v2, 0, rn);
|
||||
break;
|
||||
|
||||
case 15:
|
||||
makeface(v1, v2, v3, v4, rn);
|
||||
makeface(v1, rn->v2, v2, 0, rn);
|
||||
makeface(v2, rn->v3, v3, 0, rn);
|
||||
makeface(v3, rn->v4, v4, 0, rn);
|
||||
makeface(v4, rn->v1, v1, 0, rn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag)
|
||||
{
|
||||
switch(flag) {
|
||||
case 1:
|
||||
makeface(rn->v1, v1, rn->v3, 0, rn);
|
||||
makeface(v1, rn->v2, rn->v3, 0, rn);
|
||||
break;
|
||||
case 2:
|
||||
makeface(rn->v2, v2, rn->v1, 0, rn);
|
||||
makeface(v2, rn->v3, rn->v1, 0, rn);
|
||||
break;
|
||||
case 4:
|
||||
makeface(rn->v3, v3, rn->v2, 0, rn);
|
||||
makeface(v3, rn->v1, rn->v2, 0, rn);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
makeface(rn->v1, v2, rn->v3, 0, rn);
|
||||
makeface(rn->v1, v1, v2, 0, rn);
|
||||
makeface(v1, rn->v2, v2, 0, rn);
|
||||
break;
|
||||
case 6:
|
||||
makeface(rn->v2, v3, rn->v1, 0, rn);
|
||||
makeface(rn->v2, v2, v3, 0, rn);
|
||||
makeface(v2, rn->v3, v3, 0, rn);
|
||||
break;
|
||||
case 5:
|
||||
makeface(rn->v3, v1, rn->v2, 0, rn);
|
||||
makeface(rn->v3, v3, v1, 0, rn);
|
||||
makeface(v3, rn->v1, v1, 0, rn);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
makeface(v1, v2, v3, 0, rn);
|
||||
makeface(rn->v1, v1, v3, 0, rn);
|
||||
makeface(rn->v2, v2, v1, 0, rn);
|
||||
makeface(rn->v3, v3, v2, 0, rn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2)
|
||||
{
|
||||
int test= 0;
|
||||
|
||||
if(nb==0) return 0;
|
||||
|
||||
if(nb->ed1==node) {
|
||||
if(nb->v1==v1 || nb->v1==v2) test++;
|
||||
if(nb->v2==v1 || nb->v2==v2) test+=2;
|
||||
if(test==1) return nb->v2;
|
||||
else if(test==2) return nb->v1;
|
||||
}
|
||||
else if(nb->ed2==node) {
|
||||
if(nb->v2==v1 || nb->v2==v2) test++;
|
||||
if(nb->v3==v1 || nb->v3==v2) test+=2;
|
||||
if(test==1) return nb->v3;
|
||||
else if(test==2) return nb->v2;
|
||||
}
|
||||
else if(nb->ed3==node) {
|
||||
if(nb->type==4) {
|
||||
if(nb->v3==v1 || nb->v3==v2) test++;
|
||||
if(nb->v4==v1 || nb->v4==v2) test+=2;
|
||||
if(test==1) return nb->v4;
|
||||
else if(test==2) return nb->v3;
|
||||
|
||||
}
|
||||
else {
|
||||
if(nb->v3==v1 || nb->v3==v2) test++;
|
||||
if(nb->v1==v1 || nb->v1==v2) test+=2;
|
||||
if(test==1) return nb->v1;
|
||||
else if(test==2) return nb->v3;
|
||||
}
|
||||
}
|
||||
else if(nb->ed4==node) {
|
||||
if(nb->v4==v1 || nb->v4==v2) test++;
|
||||
if(nb->v1==v1 || nb->v1==v2) test+=2;
|
||||
if(test==1) return nb->v1;
|
||||
else if(test==2) return nb->v4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void make_face_tab() /* zorgt voor ankers */
|
||||
{
|
||||
RNode *rn, **el;
|
||||
Face *face = NULL;
|
||||
float *v1, *v2, *v3, *v4;
|
||||
int a, flag, w1, w2, w3;
|
||||
char *charcol;
|
||||
|
||||
if(RG.totelem==0) return;
|
||||
|
||||
init_face_tab();
|
||||
|
||||
RG.igamma= 1.0/RG.gamma;
|
||||
RG.radfactor= RG.radfac*pow(64*64, RG.igamma);
|
||||
|
||||
/* vlakkleuren omzetten */
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
rn= *el;
|
||||
charcol= (char *)&( rn->col );
|
||||
|
||||
charcol[3]= calculatecolor(rn->totrad[0]);
|
||||
charcol[2]= calculatecolor(rn->totrad[1]);
|
||||
charcol[1]= calculatecolor(rn->totrad[2]);
|
||||
}
|
||||
|
||||
/* nodes aflopen en Face's maken */
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
|
||||
rn= *el;
|
||||
|
||||
rn->v1[3]= 0.0;
|
||||
rn->v2[3]= 0.0;
|
||||
rn->v3[3]= 0.0;
|
||||
if(rn->v4) rn->v4[3]= 0.0;
|
||||
|
||||
/* test edges op subdivide */
|
||||
flag= 0;
|
||||
v1= v2= v3= v4= 0;
|
||||
if(rn->ed1) {
|
||||
v1= findmiddlevertex(rn, rn->ed1->down1, rn->v1, rn->v2);
|
||||
if(v1) flag |= 1;
|
||||
}
|
||||
if(rn->ed2) {
|
||||
v2= findmiddlevertex(rn, rn->ed2->down1, rn->v2, rn->v3);
|
||||
if(v2) flag |= 2;
|
||||
}
|
||||
if(rn->ed3) {
|
||||
if(rn->type==4)
|
||||
v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v4);
|
||||
else
|
||||
v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v1);
|
||||
if(v3) flag |= 4;
|
||||
}
|
||||
if(rn->ed4) {
|
||||
v4= findmiddlevertex(rn, rn->ed4->down1, rn->v4, rn->v1);
|
||||
if(v4) flag |= 8;
|
||||
}
|
||||
|
||||
/* met flag en vertexpointers kunnen nu Face's gemaakt*/
|
||||
|
||||
if(flag==0) {
|
||||
makeface(rn->v1, rn->v2, rn->v3, rn->v4, rn);
|
||||
}
|
||||
else if(rn->type==4) anchorQuadface(rn, v1, v2, v3, v4, flag);
|
||||
else anchorTriface(rn, v1, v2, v3, flag);
|
||||
}
|
||||
|
||||
/* optellen */
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
|
||||
RAD_NEXTFACE(a);
|
||||
|
||||
if(face->v4) {
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 );
|
||||
}
|
||||
else {
|
||||
triaweight(face, &w1, &w2, &w3);
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void filterFaces()
|
||||
{
|
||||
/* alle kleuren van vertices in faces en weer terug */
|
||||
|
||||
Face *face = NULL;
|
||||
int a, w1, w2, w3;
|
||||
|
||||
if(RG.totface==0) return;
|
||||
|
||||
/* wissen */
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
face->col= 0;
|
||||
}
|
||||
|
||||
/* optellen: punten bij vlakken */
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
|
||||
if(face->v4) {
|
||||
addaccuweight( (char *)(face->v1+3), (char *)&(face->col), 16 );
|
||||
addaccuweight( (char *)(face->v2+3), (char *)&(face->col), 16 );
|
||||
addaccuweight( (char *)(face->v3+3), (char *)&(face->col), 16 );
|
||||
addaccuweight( (char *)(face->v4+3), (char *)&(face->col), 16 );
|
||||
}
|
||||
else {
|
||||
triaweight(face, &w1, &w2, &w3);
|
||||
addaccuweight( (char *)(face->v1+3), (char *)&(face->col), w1 );
|
||||
addaccuweight( (char *)(face->v2+3), (char *)&(face->col), w2 );
|
||||
addaccuweight( (char *)(face->v3+3), (char *)&(face->col), w3 );
|
||||
}
|
||||
}
|
||||
|
||||
/* wissen */
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
face->v1[3]= 0.0;
|
||||
face->v2[3]= 0.0;
|
||||
face->v3[3]= 0.0;
|
||||
if(face->v4) face->v4[3]= 0.0;
|
||||
}
|
||||
|
||||
|
||||
/* optellen: vlakken bij punten */
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
|
||||
RAD_NEXTFACE(a);
|
||||
|
||||
if(face->v4) {
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 );
|
||||
}
|
||||
else {
|
||||
triaweight(face, &w1, &w2, &w3);
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 );
|
||||
addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void calcfiltrad(RNode *rn, float *cd)
|
||||
{
|
||||
float area;
|
||||
|
||||
cd[0]= 2.0*rn->totrad[0];
|
||||
cd[1]= 2.0*rn->totrad[1];
|
||||
cd[2]= 2.0*rn->totrad[2];
|
||||
area= 2.0;
|
||||
|
||||
if(rn->ed1) {
|
||||
cd[0]+= rn->ed1->totrad[0];
|
||||
cd[1]+= rn->ed1->totrad[1];
|
||||
cd[2]+= rn->ed1->totrad[2];
|
||||
area+= 1.0;
|
||||
}
|
||||
if(rn->ed2) {
|
||||
cd[0]+= rn->ed2->totrad[0];
|
||||
cd[1]+= rn->ed2->totrad[1];
|
||||
cd[2]+= rn->ed2->totrad[2];
|
||||
area+= 1.0;
|
||||
}
|
||||
if(rn->ed3) {
|
||||
cd[0]+= rn->ed3->totrad[0];
|
||||
cd[1]+= rn->ed3->totrad[1];
|
||||
cd[2]+= rn->ed3->totrad[2];
|
||||
area+= 1.0;
|
||||
}
|
||||
if(rn->ed4) {
|
||||
cd[0]+= rn->ed4->totrad[0];
|
||||
cd[1]+= rn->ed4->totrad[1];
|
||||
cd[2]+= rn->ed4->totrad[2];
|
||||
area+= 1.0;
|
||||
}
|
||||
cd[0]/= area;
|
||||
cd[1]/= area;
|
||||
cd[2]/= area;
|
||||
|
||||
}
|
||||
|
||||
void filterNodes()
|
||||
{
|
||||
/* alle kleuren van nodes in tempblok en weer terug */
|
||||
|
||||
RNode *rn, **el;
|
||||
float *coldata, *cd;
|
||||
int a;
|
||||
|
||||
if(RG.totelem==0) return;
|
||||
/* de upnodes moeten kleur hebben */
|
||||
el= RG.elem;
|
||||
for(a=0; a<RG.totelem; a++, el++) {
|
||||
rn= *el;
|
||||
if(rn->up) {
|
||||
rn->up->totrad[0]= 0.0;
|
||||
rn->up->totrad[1]= 0.0;
|
||||
rn->up->totrad[2]= 0.0;
|
||||
if(rn->up->up) {
|
||||
rn->up->up->totrad[0]= 0.0;
|
||||
rn->up->up->totrad[1]= 0.0;
|
||||
rn->up->up->totrad[2]= 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
el= RG.elem;
|
||||
for(a=0; a<RG.totelem; a++, el++) {
|
||||
rn= *el;
|
||||
if(rn->up) {
|
||||
rn->up->totrad[0]+= 0.5*rn->totrad[0];
|
||||
rn->up->totrad[1]+= 0.5*rn->totrad[1];
|
||||
rn->up->totrad[2]+= 0.5*rn->totrad[2];
|
||||
if(rn->up->up) {
|
||||
rn->up->up->totrad[0]+= 0.25*rn->totrad[0];
|
||||
rn->up->up->totrad[1]+= 0.25*rn->totrad[1];
|
||||
rn->up->up->totrad[2]+= 0.25*rn->totrad[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* met area optellen */
|
||||
cd= coldata= MEM_mallocN(3*4*RG.totelem, "filterNodes");
|
||||
el= RG.elem;
|
||||
for(a=0; a<RG.totelem; a++, el++) {
|
||||
calcfiltrad(*el, cd);
|
||||
cd+= 3;
|
||||
}
|
||||
|
||||
cd= coldata;
|
||||
el= RG.elem;
|
||||
for(a=0; a<RG.totelem; a++, el++) {
|
||||
rn= *el;
|
||||
VECCOPY(rn->totrad, cd);
|
||||
cd+= 3;
|
||||
}
|
||||
MEM_freeN(coldata);
|
||||
}
|
||||
|
||||
void removeEqualNodes(short limit)
|
||||
{
|
||||
/* nodes met kleur gelijk aan elkaar: verwijderen */
|
||||
RNode **el, *rn, *rn1;
|
||||
float thresh, f1, f2;
|
||||
int a, foundone=1, ok;
|
||||
int c1, c2;
|
||||
|
||||
if(limit==0) return;
|
||||
|
||||
thresh= 1.0/(256.0*RG.radfactor);
|
||||
thresh= 3.0*pow(thresh, RG.gamma);
|
||||
|
||||
waitcursor(1);
|
||||
|
||||
while(foundone) {
|
||||
foundone= 0;
|
||||
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>1; a--, el++) {
|
||||
rn= *el;
|
||||
rn1= *(el+1);
|
||||
|
||||
if(rn!=rn->par->first && rn1!=rn1->par->first) {
|
||||
if(rn->up && rn->up==rn1->up) {
|
||||
f1= rn->totrad[0]+ rn->totrad[1]+ rn->totrad[2];
|
||||
f2= rn1->totrad[0]+ rn1->totrad[1]+ rn1->totrad[2];
|
||||
|
||||
ok= 0;
|
||||
if(f1<thresh && f2<thresh) ok= 1;
|
||||
else {
|
||||
c1= calculatecolor(rn->totrad[0]);
|
||||
c2= calculatecolor(rn1->totrad[0]);
|
||||
|
||||
if( abs(c1-c2)<=limit ) {
|
||||
c1= calculatecolor(rn->totrad[1]);
|
||||
c2= calculatecolor(rn1->totrad[1]);
|
||||
|
||||
if( abs(c1-c2)<=limit ) {
|
||||
c1= calculatecolor(rn->totrad[2]);
|
||||
c2= calculatecolor(rn1->totrad[2]);
|
||||
|
||||
if( abs(c1-c2)<=limit ) {
|
||||
ok= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ok) {
|
||||
rn->up->totrad[0]= 0.5*(rn->totrad[0]+rn1->totrad[0]);
|
||||
rn->up->totrad[1]= 0.5*(rn->totrad[1]+rn1->totrad[1]);
|
||||
rn->up->totrad[2]= 0.5*(rn->totrad[2]+rn1->totrad[2]);
|
||||
rn1= rn->up;
|
||||
deleteNodes(rn1);
|
||||
if(rn1->down1) ;
|
||||
else {
|
||||
foundone++;
|
||||
a--; el++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(foundone) {
|
||||
makeGlobalElemArray();
|
||||
}
|
||||
}
|
||||
waitcursor(0);
|
||||
}
|
||||
|
||||
#define BLSIZE 32000
|
||||
|
||||
void rad_addmesh(void)
|
||||
{
|
||||
Face *face = NULL;
|
||||
Object *ob;
|
||||
Mesh *me;
|
||||
MVert *mvert;
|
||||
MFace *mface;
|
||||
Material *ma=0;
|
||||
unsigned int *md, *coldata, *cd;
|
||||
float **fpp, **poindata;
|
||||
float cent[3], min[3], max[3];
|
||||
int a, vcount, vlnr, startf, endf;
|
||||
|
||||
if(RG.totface==0) return;
|
||||
|
||||
/* make sure there's alpha in the color, to distinguish */
|
||||
for(a=0; a<RG.totface; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
*((unsigned int *)face->v1+3) |= 0x1000000;
|
||||
*((unsigned int *)face->v2+3) |= 0x1000000;
|
||||
*((unsigned int *)face->v3+3) |= 0x1000000;
|
||||
if(face->v4) {
|
||||
*((unsigned int *)face->v4+3) |= 0x1000000;
|
||||
}
|
||||
}
|
||||
|
||||
/* we write in blocks of BLSIZE vertices max */
|
||||
coldata= MEM_mallocN(4*BLSIZE, "writefaces");
|
||||
poindata= MEM_mallocN(sizeof(void *)*BLSIZE, "writefaces1");
|
||||
|
||||
vlnr= 0;
|
||||
endf= 0;
|
||||
while(endf<RG.totface) {
|
||||
|
||||
cd= coldata;
|
||||
fpp= poindata;
|
||||
startf= endf;
|
||||
vcount= 0;
|
||||
|
||||
face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023);
|
||||
for(vlnr=startf; vlnr<RG.totface; vlnr++) {
|
||||
RAD_NEXTFACE(vlnr);
|
||||
|
||||
if( *((unsigned int *)face->v1+3) & 0x1000000 ) { /* is a color */
|
||||
*cd= *((unsigned int *)face->v1+3);
|
||||
*((unsigned int *)face->v1+3) = vcount;
|
||||
*fpp= face->v1;
|
||||
fpp++; vcount++; cd++;
|
||||
}
|
||||
if( *((unsigned int *)face->v2+3) & 0x1000000 ) {
|
||||
*cd= *((unsigned int *)face->v2+3);
|
||||
*((unsigned int *)face->v2+3) = vcount;
|
||||
*fpp= face->v2;
|
||||
fpp++; vcount++; cd++;
|
||||
}
|
||||
if( *((unsigned int *)face->v3+3) & 0x1000000 ) {
|
||||
*cd= *((unsigned int *)face->v3+3);
|
||||
*((unsigned int *)face->v3+3) = vcount;
|
||||
*fpp= face->v3;
|
||||
fpp++; vcount++; cd++;
|
||||
}
|
||||
if(face->v4 && ( *((unsigned int *)face->v4+3) & 0x1000000 ) ) {
|
||||
*cd= *((unsigned int *)face->v4+3);
|
||||
*((unsigned int *)face->v4+3) = vcount;
|
||||
*fpp= face->v4;
|
||||
fpp++; vcount++; cd++;
|
||||
}
|
||||
|
||||
if(vcount>=BLSIZE-4) {
|
||||
vlnr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* we now make the Mesh */
|
||||
endf= vlnr;
|
||||
|
||||
ob= add_object(OB_MESH);
|
||||
|
||||
me= ob->data;
|
||||
me->totvert= vcount;
|
||||
me->totface= endf-startf;
|
||||
me->flag= 0;
|
||||
me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
|
||||
me->mcol= MEM_callocN(4*me->totface*sizeof(MCol), "mverts");
|
||||
me->mface= MEM_callocN(me->totface*sizeof(MFace), "mface");
|
||||
|
||||
|
||||
/* materials, and set VCOL flag */
|
||||
for(a=0; a<RG.totmat; a++) {
|
||||
assign_material(ob, RG.matar[a], a+1);
|
||||
ma= RG.matar[a];
|
||||
if(ma) ma->mode |= MA_VERTEXCOL;
|
||||
}
|
||||
|
||||
/* verts */
|
||||
mvert= me->mvert;
|
||||
fpp= poindata;
|
||||
for(a=0; a<me->totvert; a++, mvert++, fpp++) {
|
||||
VECCOPY(mvert->co, *fpp);
|
||||
}
|
||||
|
||||
/* faces and mcol */
|
||||
mface= me->mface;
|
||||
md= (unsigned int *)me->mcol;
|
||||
|
||||
face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023);
|
||||
for(a=startf; a<endf; a++, md+=4, mface++) {
|
||||
RAD_NEXTFACE(a);
|
||||
mface->v1= *((unsigned int *)face->v1+3);
|
||||
mface->v2= *((unsigned int *)face->v2+3);
|
||||
mface->v3= *((unsigned int *)face->v3+3);
|
||||
if(face->v4) mface->v4= *((unsigned int *)face->v4+3);
|
||||
|
||||
mface->edcode= 3;
|
||||
test_index_mface(mface, face->v4 ? 4 : 3);
|
||||
mface->mat_nr= face->matindex;
|
||||
|
||||
md[0]= coldata[mface->v1];
|
||||
md[1]= coldata[mface->v2];
|
||||
md[2]= coldata[mface->v3];
|
||||
md[3]= coldata[mface->v4];
|
||||
}
|
||||
|
||||
/* boundbox en centrenew */
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totvert; a++, mvert++) {
|
||||
DO_MINMAX(mvert->co, min, max);
|
||||
}
|
||||
|
||||
cent[0]= (min[0]+max[0])/2.0;
|
||||
cent[1]= (min[1]+max[1])/2.0;
|
||||
cent[2]= (min[2]+max[2])/2.0;
|
||||
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totvert; a++, mvert++) {
|
||||
VecSubf(mvert->co, mvert->co, cent);
|
||||
}
|
||||
|
||||
VECCOPY(ob->loc, cent);
|
||||
tex_space_mesh(me);
|
||||
|
||||
/* restore colors */
|
||||
face= RG.facebase[(startf-1)>>10]+((startf-1) & 1023);
|
||||
for(a=startf; a<endf; a++) {
|
||||
RAD_NEXTFACE(a);
|
||||
|
||||
cd= ((unsigned int *)face->v1+3);
|
||||
if( *cd < 0x1000000 ) *cd= coldata[*cd];
|
||||
cd= ((unsigned int *)face->v2+3);
|
||||
if( *cd < 0x1000000 ) *cd= coldata[*cd];
|
||||
cd= ((unsigned int *)face->v3+3);
|
||||
if( *cd < 0x1000000 ) *cd= coldata[*cd];
|
||||
if(face->v4) {
|
||||
cd= ((unsigned int *)face->v4+3);
|
||||
if( *cd < 0x1000000 ) *cd= coldata[*cd];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(coldata);
|
||||
MEM_freeN(poindata);
|
||||
|
||||
}
|
||||
|
||||
void rad_replacemesh(void)
|
||||
{
|
||||
RPatch *rp;
|
||||
|
||||
deselectall();
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
if( exist_object(rp->from)) rp->from->flag |= SELECT;
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
copy_objectflags();
|
||||
delete_obj(1);
|
||||
|
||||
rad_addmesh();
|
||||
}
|
||||
|
787
source/blender/radiosity/intern/source/radpreprocess.c
Normal file
787
source/blender/radiosity/intern/source/radpreprocess.c
Normal file
@@ -0,0 +1,787 @@
|
||||
/* ***************************************
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
|
||||
|
||||
|
||||
preproces.c nov/dec 1992
|
||||
may 1999
|
||||
|
||||
- collect from meshes
|
||||
- countglobaldata()
|
||||
- makeGlobalElemArray()
|
||||
|
||||
$Id$
|
||||
|
||||
*************************************** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#include "radio.h"
|
||||
|
||||
void setparelem(RNode *rn, RPatch *par);
|
||||
|
||||
|
||||
|
||||
void splitconnected()
|
||||
{
|
||||
/* voor zover de videoscapefile nog gedeelde vertices leverde, worden de vlakken getest
|
||||
* op normaal en kleur. Doe dit door voor elke vertex een normaal en een kleur te onthouden.
|
||||
*/
|
||||
RPatch *rp;
|
||||
RNode *rn;
|
||||
VeNoCo *vnc, *next, *vnc1;
|
||||
int a;
|
||||
|
||||
/* test of gesplit moet worden */
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
rn= rp->first;
|
||||
if((rp->f1 & RAD_NO_SPLIT)==0) {
|
||||
for(a=0; a<rp->type; a++) {
|
||||
|
||||
if(a==0) vnc= (VeNoCo *)rn->v1;
|
||||
else if(a==1) vnc= (VeNoCo *)rn->v2;
|
||||
else if(a==2) vnc= (VeNoCo *)rn->v3;
|
||||
else vnc= (VeNoCo *)rn->v4;
|
||||
|
||||
if(vnc->flag==0) {
|
||||
vnc->n= (float *)rp->norm;
|
||||
vnc->col= (float *)rp->ref;
|
||||
vnc->flag= 1;
|
||||
}
|
||||
else { /* mag vlak deze vertex gebruiken voor gouraud? */
|
||||
vnc1= vnc;
|
||||
while(vnc1) {
|
||||
if(VecCompare(vnc1->n, rp->norm, 0.01)) {
|
||||
if(VecCompare(vnc1->col, rp->ref, 0.01)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
vnc= vnc1;
|
||||
vnc1= vnc1->next;
|
||||
}
|
||||
if(vnc1==0) {
|
||||
vnc1= MEM_mallocN(sizeof(VeNoCo), "splitconn");
|
||||
vnc1->next= 0;
|
||||
vnc1->v= mallocVert();
|
||||
vnc->next= vnc1;
|
||||
VECCOPY(vnc1->v, vnc->v);
|
||||
vnc1->n= (float *)rp->norm;
|
||||
vnc1->col= (float *)rp->ref;
|
||||
}
|
||||
if(a==0) rn->v1= (float *)vnc1;
|
||||
else if(a==1) rn->v2= (float *)vnc1;
|
||||
else if(a==2) rn->v3= (float *)vnc1;
|
||||
else rn->v4= (float *)vnc1;
|
||||
}
|
||||
}
|
||||
}
|
||||
rp= rp->next;
|
||||
}
|
||||
/* de vertexpointers van nodes aanpassen */
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
rn= rp->first;
|
||||
rn->v1= ((VeNoCo *)(rn->v1))->v;
|
||||
rn->v2= ((VeNoCo *)(rn->v2))->v;
|
||||
rn->v3= ((VeNoCo *)(rn->v3))->v;
|
||||
if(rp->type==4) rn->v4= ((VeNoCo *)(rn->v4))->v;
|
||||
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
|
||||
/* het hele zaakje vrijgeven */
|
||||
vnc= RG.verts;
|
||||
for(a=0; a<RG.totvert; a++) {
|
||||
vnc1= vnc->next;
|
||||
while(vnc1) {
|
||||
next= vnc1->next;
|
||||
MEM_freeN(vnc1);
|
||||
vnc1= next;
|
||||
}
|
||||
vnc++;
|
||||
}
|
||||
MEM_freeN(RG.verts);
|
||||
RG.verts= 0;
|
||||
}
|
||||
|
||||
int vergedge(const void *v1,const void *v2)
|
||||
{
|
||||
int *e1, *e2;
|
||||
|
||||
e1= (int *)v1;
|
||||
e2= (int *)v2;
|
||||
|
||||
if( e1[0] > e2[0] ) return 1;
|
||||
else if( e1[0] < e2[0] ) return -1;
|
||||
else if( e1[1] > e2[1] ) return 1;
|
||||
else if( e1[1] < e2[1] ) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void addedge(float *v1, float *v2, EdSort *es)
|
||||
{
|
||||
if( ((long)v1)<((long)v2) ) {
|
||||
es->v1= v1;
|
||||
es->v2= v2;
|
||||
}
|
||||
else {
|
||||
es->v2= v1;
|
||||
es->v1= v2;
|
||||
}
|
||||
}
|
||||
|
||||
static void setedge(RNode *node, RNode *nb, int nr, int nrb)
|
||||
{
|
||||
switch(nr) {
|
||||
case 1:
|
||||
node->ed1= nb;
|
||||
break;
|
||||
case 2:
|
||||
node->ed2= nb;
|
||||
break;
|
||||
case 3:
|
||||
node->ed3= nb;
|
||||
break;
|
||||
case 4:
|
||||
node->ed4= nb;
|
||||
break;
|
||||
}
|
||||
switch(nrb) {
|
||||
case 1:
|
||||
nb->ed1= node;
|
||||
break;
|
||||
case 2:
|
||||
nb->ed2= node;
|
||||
break;
|
||||
case 3:
|
||||
nb->ed3= node;
|
||||
break;
|
||||
case 4:
|
||||
nb->ed4= node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setedgepointers()
|
||||
{
|
||||
/* edge-array maken en sorteren */
|
||||
/* paren edges staan bij elkaar: pointers invullen in nodes */
|
||||
EdSort *es, *esblock;
|
||||
RPatch *rp;
|
||||
RNode *rn;
|
||||
int tot= 0;
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
tot+= rp->type;
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
if(tot==0) return;
|
||||
|
||||
es=esblock= MEM_mallocN(tot*sizeof(EdSort), "setedgepointers");
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
rn= rp->first;
|
||||
addedge(rn->v1, rn->v2, es);
|
||||
es->nr= 1;
|
||||
es->node= rn;
|
||||
es++;
|
||||
addedge(rn->v2, rn->v3, es);
|
||||
es->nr= 2;
|
||||
es->node= rn;
|
||||
es++;
|
||||
if(rp->type==3) {
|
||||
addedge(rn->v3, rn->v1, es);
|
||||
es->nr= 3;
|
||||
es->node= rn;
|
||||
es++;
|
||||
}
|
||||
else {
|
||||
addedge(rn->v3, rn->v4, es);
|
||||
es->nr= 3;
|
||||
es->node= rn;
|
||||
es++;
|
||||
addedge(rn->v4, rn->v1, es);
|
||||
es->nr= 4;
|
||||
es->node= rn;
|
||||
es++;
|
||||
}
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
qsort(esblock,tot,sizeof(EdSort),vergedge);
|
||||
|
||||
es= esblock;
|
||||
while(tot>0) {
|
||||
if( es->v1== (es+1)->v1 ) {
|
||||
if( es->v2== (es+1)->v2 ) {
|
||||
setedge(es->node, (es+1)->node, es->nr, (es+1)->nr);
|
||||
tot--;
|
||||
es++;
|
||||
}
|
||||
}
|
||||
es++;
|
||||
tot--;
|
||||
}
|
||||
|
||||
MEM_freeN(esblock);
|
||||
}
|
||||
|
||||
void rad_collect_meshes()
|
||||
{
|
||||
extern Material defmaterial;
|
||||
Base *base;
|
||||
Object *ob;
|
||||
Mesh *me;
|
||||
MVert *mvert;
|
||||
MFace *mface;
|
||||
Material *ma = NULL, *noma= NULL;
|
||||
RPatch *rp;
|
||||
RNode *rn;
|
||||
VeNoCo *vnc, **nodevert;
|
||||
float *vd, *v1, *v2, *v3, *v4 = NULL;
|
||||
int a, b, offs, index, matindex;
|
||||
|
||||
if(G.obedit) {
|
||||
error("Unable to perform function in EditMode");
|
||||
return;
|
||||
}
|
||||
|
||||
set_radglobal();
|
||||
|
||||
freeAllRad();
|
||||
|
||||
start_fastmalloc("Radiosity");
|
||||
|
||||
/* count the number of verts */
|
||||
RG.totvert= 0;
|
||||
RG.totface= 0;
|
||||
base= (G.scene->base.first);
|
||||
while(base) {
|
||||
if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
base->flag |= OB_RADIO;
|
||||
me= base->object->data;
|
||||
RG.totvert+= me->totvert;
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
if(RG.totvert==0) {
|
||||
error("No vertices");
|
||||
return;
|
||||
}
|
||||
vnc= RG.verts= MEM_callocN(RG.totvert*sizeof(VeNoCo), "readvideoscape1");
|
||||
|
||||
RG.min[0]= RG.min[1]= RG.min[2]= 1.0e20;
|
||||
RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20;
|
||||
|
||||
/* min-max and material array */
|
||||
base= (G.scene->base.first);
|
||||
while(base) {
|
||||
if( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totvert; a++, mvert++) {
|
||||
vd= mallocVert();
|
||||
VECCOPY(vd, mvert->co);
|
||||
/* Should make MTC its own module... */
|
||||
Mat4MulVecfl(base->object->obmat, vd);
|
||||
|
||||
vnc->v= vd;
|
||||
for(b=0; b<3; b++) {
|
||||
RG.min[b]= MIN2(RG.min[b], vd[b]);
|
||||
RG.max[b]= MAX2(RG.max[b], vd[b]);
|
||||
}
|
||||
vnc++;
|
||||
}
|
||||
|
||||
if(base->object->totcol==0) {
|
||||
if(RG.totmat<MAXMAT) {
|
||||
if(noma==NULL) {
|
||||
noma= add_material("RadioMat");
|
||||
}
|
||||
RG.matar[RG.totmat]= noma;
|
||||
RG.totmat++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(a=0; a<base->object->totcol; a++) {
|
||||
if(a+RG.totmat>MAXMAT-1) break;
|
||||
RG.matar[a+RG.totmat]= give_current_material(base->object, a+1);
|
||||
}
|
||||
|
||||
RG.totmat+= base->object->totcol;
|
||||
if (RG.totmat >= MAXMAT) {
|
||||
RG.totmat = MAXMAT - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
RG.cent[0]= (RG.min[0]+ RG.max[0])/2;
|
||||
RG.cent[1]= (RG.min[1]+ RG.max[1])/2;
|
||||
RG.cent[2]= (RG.min[2]+ RG.max[2])/2;
|
||||
RG.size[0]= (RG.max[0]- RG.min[0]);
|
||||
RG.size[1]= (RG.max[1]- RG.min[1]);
|
||||
RG.size[2]= (RG.max[2]- RG.min[2]);
|
||||
RG.maxsize= MAX3(RG.size[0],RG.size[1],RG.size[2]);
|
||||
|
||||
/* make patches */
|
||||
|
||||
RG.totelem= 0;
|
||||
RG.totpatch= 0;
|
||||
RG.totlamp= 0;
|
||||
offs= 0;
|
||||
matindex= 0;
|
||||
|
||||
base= (G.scene->base.first);
|
||||
while(base) {
|
||||
if( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
ob= base->object;
|
||||
me= ob->data;
|
||||
mface= me->mface;
|
||||
|
||||
index= -1;
|
||||
|
||||
for(a=0; a<me->totface; a++, mface++) {
|
||||
if(mface->v3) {
|
||||
|
||||
rp= callocPatch();
|
||||
BLI_addtail(&(RG.patchbase), rp);
|
||||
rp->from= ob;
|
||||
|
||||
if(mface->v4) rp->type= 4;
|
||||
else rp->type= 3;
|
||||
|
||||
rp->first= rn= callocNode();
|
||||
|
||||
if(mface->flag & ME_SMOOTH) rp->f1= RAD_NO_SPLIT;
|
||||
|
||||
/* temporal: we store the venoco in the node */
|
||||
rn->v1= (float *)(RG.verts+mface->v1+offs);
|
||||
v1= (RG.verts+mface->v1+offs)->v;
|
||||
rn->v2= (float *)(RG.verts+mface->v2+offs);
|
||||
v2= (RG.verts+mface->v2+offs)->v;
|
||||
rn->v3= (float *)(RG.verts+mface->v3+offs);
|
||||
v3= (RG.verts+mface->v3+offs)->v;
|
||||
|
||||
if(mface->v4) {
|
||||
rn->v4= (float *)(RG.verts+mface->v4+offs);
|
||||
v4= (RG.verts+mface->v4+offs)->v;
|
||||
}
|
||||
rn->par= rp;
|
||||
rn->f= RAD_PATCH; /* deze node is Patch */
|
||||
rn->type= rp->type;
|
||||
|
||||
CalcNormFloat(v1, v2, v3, rp->norm);
|
||||
if(rn->type==4) rp->area= AreaQ3Dfl(v1, v2, v3, v4);
|
||||
else rp->area= AreaT3Dfl(v1, v2, v3);
|
||||
|
||||
rn->area= rp->area;
|
||||
|
||||
/* kleur en emit */
|
||||
if(mface->mat_nr != index) {
|
||||
index= mface->mat_nr;
|
||||
ma= give_current_material(ob, index+1);
|
||||
if(ma==0) ma= &defmaterial;
|
||||
}
|
||||
rp->ref[0]= ma->r;
|
||||
rp->ref[1]= ma->g;
|
||||
rp->ref[2]= ma->b;
|
||||
|
||||
if(ma->emit) RG.totlamp++;
|
||||
|
||||
rp->emit[0]= rp->emit[1]= rp->emit[2]= ma->emit;
|
||||
rp->emit[0]*= rp->ref[0];
|
||||
rp->emit[1]*= rp->ref[1];
|
||||
rp->emit[2]*= rp->ref[2];
|
||||
|
||||
nodevert= (VeNoCo **)&(rn->v1);
|
||||
for(b=0; b<rp->type; b++) {
|
||||
rp->cent[0]+= (*nodevert)->v[0];
|
||||
rp->cent[1]+= (*nodevert)->v[1];
|
||||
rp->cent[2]+= (*nodevert)->v[2];
|
||||
nodevert++;
|
||||
}
|
||||
rp->cent[0]/= (float)rp->type;
|
||||
rp->cent[1]/= (float)rp->type;
|
||||
rp->cent[2]/= (float)rp->type;
|
||||
|
||||
/* for reconstruction materials */
|
||||
rp->matindex= matindex+mface->mat_nr;
|
||||
if(rp->matindex>MAXMAT-1) rp->matindex= MAXMAT-1;
|
||||
|
||||
RG.totelem++;
|
||||
RG.totpatch++;
|
||||
}
|
||||
}
|
||||
offs+= me->totvert;
|
||||
|
||||
matindex+= base->object->totcol;
|
||||
if(base->object->totcol==0) matindex++;
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
splitconnected();
|
||||
setedgepointers();
|
||||
|
||||
makeGlobalElemArray();
|
||||
pseudoAmb();
|
||||
rad_setlimits();
|
||||
}
|
||||
|
||||
void setparelem(RNode *rn, RPatch *par)
|
||||
{
|
||||
|
||||
if(rn->down1) {
|
||||
setparelem(rn->down1, par);
|
||||
setparelem(rn->down2, par);
|
||||
}
|
||||
else {
|
||||
rn->par= par;
|
||||
}
|
||||
}
|
||||
|
||||
void countelem(RNode *rn)
|
||||
{
|
||||
|
||||
if(rn->down1) {
|
||||
countelem(rn->down1);
|
||||
countelem(rn->down2);
|
||||
}
|
||||
else RG.totelem++;
|
||||
}
|
||||
|
||||
void countglobaldata()
|
||||
{
|
||||
/* telt aantal elements en patches*/
|
||||
RPatch *rp;
|
||||
|
||||
RG.totelem= RG.totpatch= 0;
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
RG.totpatch++;
|
||||
countelem(rp->first);
|
||||
rp= rp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void addelem(RNode ***el, RNode *rn, RPatch *rp)
|
||||
{
|
||||
if(rn->down1) {
|
||||
addelem(el, rn->down1, rp);
|
||||
addelem(el, rn->down2, rp);
|
||||
}
|
||||
else {
|
||||
rn->par= rp;
|
||||
**el= rn;
|
||||
(*el)++;
|
||||
}
|
||||
}
|
||||
|
||||
void makeGlobalElemArray()
|
||||
{
|
||||
/* always called when # of elements change */
|
||||
RPatch *rp;
|
||||
RNode **el;
|
||||
|
||||
countglobaldata();
|
||||
|
||||
if(RG.elem) MEM_freeN(RG.elem);
|
||||
if(RG.totelem) {
|
||||
el= RG.elem= MEM_mallocN(sizeof(void *)*RG.totelem, "makeGlobalElemArray");
|
||||
}
|
||||
else {
|
||||
RG.elem= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* recursief elements toevoegen */
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
addelem(&el, rp->first, rp);
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
/* formfactor array */
|
||||
if(RG.formfactors) MEM_freeN(RG.formfactors);
|
||||
if(RG.totelem)
|
||||
RG.formfactors= MEM_mallocN(sizeof(float)*RG.totelem, "formfactors");
|
||||
else
|
||||
RG.formfactors= 0;
|
||||
}
|
||||
|
||||
void splitpatch(RPatch *old) /* bij overflow gedurende shoot */
|
||||
{
|
||||
RNode *rn;
|
||||
float **fpp;
|
||||
RPatch *rp;
|
||||
int a;
|
||||
|
||||
rn= old->first;
|
||||
if(rn->down1==0) return;
|
||||
rn= rn->down1;
|
||||
|
||||
old->unshot[0]/=2.0;
|
||||
old->unshot[1]/=2.0;
|
||||
old->unshot[2]/=2.0;
|
||||
setnodeflags(old->first, 2, 0);
|
||||
|
||||
rp= mallocPatch();
|
||||
*rp= *old;
|
||||
BLI_addhead(&RG.patchbase, rp);
|
||||
rp->first= rn;
|
||||
rp->area= rn->area;
|
||||
rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0;
|
||||
fpp= &(rn->v1);
|
||||
for(a=0; a<rp->type; a++) {
|
||||
rp->cent[0]+= (*fpp)[0];
|
||||
rp->cent[1]+= (*fpp)[1];
|
||||
rp->cent[2]+= (*fpp)[2];
|
||||
fpp++;
|
||||
}
|
||||
rp->cent[0]/=(float)rp->type;
|
||||
rp->cent[1]/=(float)rp->type;
|
||||
rp->cent[2]/=(float)rp->type;
|
||||
|
||||
setparelem(rn, rp);
|
||||
|
||||
rn= old->first->down2;
|
||||
|
||||
rp= mallocPatch();
|
||||
*rp= *old;
|
||||
BLI_addhead(&RG.patchbase, rp);
|
||||
rp->first= rn;
|
||||
rp->area= rn->area;
|
||||
rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0;
|
||||
fpp= &(rn->v1);
|
||||
for(a=0; a<rp->type; a++) {
|
||||
rp->cent[0]+= (*fpp)[0];
|
||||
rp->cent[1]+= (*fpp)[1];
|
||||
rp->cent[2]+= (*fpp)[2];
|
||||
fpp++;
|
||||
}
|
||||
rp->cent[0]/=(float)rp->type;
|
||||
rp->cent[1]/=(float)rp->type;
|
||||
rp->cent[2]/=(float)rp->type;
|
||||
|
||||
setparelem(rn, rp);
|
||||
|
||||
BLI_remlink(&RG.patchbase, old);
|
||||
freePatch(old);
|
||||
}
|
||||
|
||||
|
||||
void addpatch(RPatch *old, RNode *rn)
|
||||
{
|
||||
float **fpp;
|
||||
RPatch *rp;
|
||||
int a;
|
||||
|
||||
if(rn->down1) {
|
||||
addpatch(old, rn->down1);
|
||||
addpatch(old, rn->down2);
|
||||
}
|
||||
else {
|
||||
rp= mallocPatch();
|
||||
*rp= *old;
|
||||
BLI_addhead(&RG.patchbase, rp);
|
||||
rp->first= rn;
|
||||
|
||||
rp->area= rn->area;
|
||||
rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0;
|
||||
fpp= &(rn->v1);
|
||||
for(a=0; a<rp->type; a++) {
|
||||
rp->cent[0]+= (*fpp)[0];
|
||||
rp->cent[1]+= (*fpp)[1];
|
||||
rp->cent[2]+= (*fpp)[2];
|
||||
fpp++;
|
||||
}
|
||||
rp->cent[0]/=(float)rp->type;
|
||||
rp->cent[1]/=(float)rp->type;
|
||||
rp->cent[2]/=(float)rp->type;
|
||||
|
||||
rn->par= rp;
|
||||
}
|
||||
}
|
||||
|
||||
void converttopatches()
|
||||
{
|
||||
/* loopt patcheslijst af, als node gesubdivided: nieuwe patch */
|
||||
RPatch *rp, *next;
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
next= rp->next;
|
||||
if(rp->first->down1) {
|
||||
addpatch(rp, rp->first);
|
||||
BLI_remlink(&RG.patchbase, rp);
|
||||
freePatch(rp);
|
||||
}
|
||||
rp= next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void subdiv_elements()
|
||||
{
|
||||
RNode **el, *rn;
|
||||
int a, toobig= 1;
|
||||
|
||||
rad_init_energy();
|
||||
|
||||
/* eerst maxsize elements */
|
||||
|
||||
while(toobig) {
|
||||
toobig= 0;
|
||||
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
rn= *el;
|
||||
if( rn->totrad[0]==0.0 && rn->totrad[1]==0.0 && rn->totrad[2]==0.0) {
|
||||
if(rn->area>RG.elemmin) {
|
||||
subdivideNode(rn, 0);
|
||||
if(rn->down1 ) {
|
||||
toobig= 1;
|
||||
if(rn->down1->area>RG.elemmin)
|
||||
subdivideNode( rn->down1, 0);
|
||||
if(rn->down2->area>RG.elemmin)
|
||||
subdivideNode( rn->down2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(toobig) makeGlobalElemArray();
|
||||
}
|
||||
|
||||
el= RG.elem;
|
||||
for(a=RG.totelem; a>0; a--, el++) {
|
||||
rn= *el;
|
||||
if( rn->totrad[0]==0.0 && rn->totrad[1]==0.0 && rn->totrad[2]==0.0) {
|
||||
subdivideNode(rn, 0);
|
||||
if( rn->down1 ) {
|
||||
subdivideNode( rn->down1, 0);
|
||||
subdivideNode( rn->down2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
makeGlobalElemArray();
|
||||
}
|
||||
|
||||
void subdividelamps()
|
||||
{
|
||||
RPatch *rp, *next;
|
||||
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
next= rp->next;
|
||||
if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) {
|
||||
subdivideNode( rp->first, 0);
|
||||
if(rp->first->down1) {
|
||||
subdivideNode(rp->first->down1, 0);
|
||||
subdivideNode(rp->first->down2, 0);
|
||||
}
|
||||
|
||||
addpatch(rp, rp->first);
|
||||
BLI_remlink(&RG.patchbase, rp);
|
||||
freePatch(rp);
|
||||
}
|
||||
rp= next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void maxsizePatches()
|
||||
{
|
||||
RPatch *rp;
|
||||
int toobig= 1;
|
||||
|
||||
while(toobig) {
|
||||
toobig= 0;
|
||||
rp= RG.patchbase.first;
|
||||
while(rp) {
|
||||
if(rp->area>RG.patchmax) {
|
||||
subdivideNode( rp->first, 0);
|
||||
if(rp->first->down1) toobig= 1;
|
||||
}
|
||||
rp= rp->next;
|
||||
}
|
||||
|
||||
if(toobig) converttopatches();
|
||||
}
|
||||
|
||||
/* aantal lampen tellen */
|
||||
rp= RG.patchbase.first;
|
||||
RG.totlamp= 0;
|
||||
while(rp) {
|
||||
if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) {
|
||||
RG.totlamp++;
|
||||
}
|
||||
rp= rp->next;
|
||||
}
|
||||
makeGlobalElemArray();
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user