1 //////////////////////////////////////////////////////////////////////
2 //
3 //                             Pixie
4 //
5 // Copyright � 1999 - 2003, Okan Arikan
6 //
7 // Contact: okan@cs.utexas.edu
8 //
9 //	This library is free software; you can redistribute it and/or
10 //	modify it under the terms of the GNU Lesser General Public
11 //	License as published by the Free Software Foundation; either
12 //	version 2.1 of the License, or (at your option) any later version.
13 //
14 //	This library is distributed in the hope that it will be useful,
15 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 //	Lesser General Public License for more details.
18 //
19 //	You should have received a copy of the GNU Lesser General Public
20 //	License along with this library; if not, write to the Free Software
21 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 //
23 ///////////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////////
25 //
26 //  File				:	giOpcodes.h
27 //  Classes				:	-
28 //  Description			:	Shading language Global Illumination opcodes.
29 //
30 ////////////////////////////////////////////////////////////////////////
31 
32 
33 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34 //	gather <else>
35 #ifndef INIT_SHADING
36 #define	GATHEREXPR_PRE		const int		numRealVertices	=	currentShadingState->numRealVertices;	\
37 							CGatherRay		*raysBase		=	lastGather->raysBase;					\
38 							CGatherRay		**rays			=	(CGatherRay **) lastGather->raysStorage;\
39 							const float 	temp			=	1 / (float) (lastGather->numSamples);	\
40 							const float		*N				=	varying[VARIABLE_N];					\
41 							const float		*time			=	varying[VARIABLE_TIME];					\
42 							int				numIntRays		=	0;										\
43 							int				numExtRays		=	0;										\
44 							const CAttributes	*cAttributes	=	currentShadingState->currentObject->attributes;		\
45 							const int			sampleMotion	=	cAttributes->flags & ATTRIBUTES_FLAGS_SAMPLEMOTION;	\
46 							for (int i=0;i<numRealVertices;++i) {										\
47 								if (tags[i]) {															\
48 									++tags[i];															\
49 								} else {																\
50 									vector	tmp0,tmp1;													\
51 									mulvf(tmp0,raysBase->dPdu,raysBase->sampleBase*(urand() - 0.5f));	\
52 									mulvf(tmp1,raysBase->dPdv,raysBase->sampleBase*(urand() - 0.5f));	\
53 									addvv(raysBase->from,tmp0,tmp1);									\
54 									addvv(raysBase->from,raysBase->gatherP);							\
55 																										\
56 									if (lastGather->uniformDist) {										\
57 										sampleHemisphere(raysBase->dir,raysBase->gatherDir,raysBase->sampleCone,random4d);			\
58 									} else {															\
59 										sampleCosineHemisphere(raysBase->dir,raysBase->gatherDir,raysBase->sampleCone,random4d);	\
60 									}																	\
61 									raysBase->index	=	i;												\
62 									raysBase->tmin	=	raysBase->bias;									\
63 									raysBase->t		=	raysBase->maxDist;								\
64 									if (sampleMotion)	raysBase->time	=	(urand() + lastGather->remainingSamples - 1) * temp;	\
65 									else				raysBase->time	=	time[0];					\
66 									raysBase->flags	=	ATTRIBUTES_FLAGS_DIFFUSE_VISIBLE | ATTRIBUTES_FLAGS_SPECULAR_VISIBLE;		\
67 									raysBase->tags	=	&tags[i];										\
68 									if (dotvv(raysBase->dir,N) > 0) {									\
69 										rays[numExtRays++] = raysBase;									\
70 									} else {															\
71 										rays[numRealVertices-1-numIntRays++] = raysBase;				\
72 									}																	\
73 								}																		\
74 								raysBase++;																\
75 								N		+=	3;															\
76 								++time;																	\
77 							}																			\
78 							if ( (numIntRays+numExtRays) > 0 ) {										\
79 								if (numIntRays > 0) {													\
80 									lastGather->numRays		=	numIntRays;								\
81 									lastGather->rays		=	(CRay **) rays+numRealVertices-numIntRays;	\
82 									lastGather->last		=	0;										\
83 									lastGather->depth		=	0;										\
84 									lastGather->postShader	=	cAttributes->interior;					\
85 									lastGather->numMisses	=	0;										\
86 									traceEx(lastGather);												\
87 									numActive				-=	lastGather->numMisses;					\
88 									numPassive				+=	lastGather->numMisses;					\
89 								}																		\
90 								if (numExtRays > 0) {													\
91 									lastGather->numRays		=	numExtRays;								\
92 									lastGather->rays		=	(CRay **) rays;							\
93 									lastGather->last		=	0;										\
94 									lastGather->depth		=	0;										\
95 									lastGather->postShader	=	cAttributes->exterior;					\
96 									lastGather->numMisses	=	0;										\
97 									traceEx(lastGather);												\
98 									numActive				-=	lastGather->numMisses;					\
99 									numPassive				+=	lastGather->numMisses;					\
100 								}																		\
101 																										\
102 								if (numActive == 0) {													\
103 									jmp(argument(0));													\
104 								}																		\
105 							}
106 
107 #else
108 #define GATHEREXPR_PRE
109 #endif
110 
111 DEFOPCODE(Gather	,"gather"	,1,	GATHEREXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,PARAMETER_N | PARAMETER_RAYTRACE)
112 
113 #undef GATHEREXPR_PRE
114 
115 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 //	gatheElse <endLabel>
117 #ifndef INIT_SHADING
118 #define	GATHERELSEEXPR_PRE	int	numRealVertices = currentShadingState->numRealVertices;				\
119 																									\
120 							for (;numRealVertices>0;numRealVertices--,tags++)	{					\
121 								if (*tags <= 1) {													\
122 									if (*tags == 1) {												\
123 										*tags	=	0;												\
124 										numActive++;												\
125 										numPassive--;												\
126 									} else {														\
127 										*tags	=	1;												\
128 										numActive--;												\
129 										numPassive++;												\
130 									}																\
131 								}																	\
132 							}																		\
133 																									\
134 							if (numActive == 0) {													\
135 								jmp(argument(0));													\
136 							}
137 
138 #else
139 #define GATHERELSEEXPR_PRE
140 #endif
141 
142 DEFOPCODE(GatherElse	,"gatherElse"	,1,	GATHERELSEEXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,0)
143 
144 #undef GATHERELSEEXPR_PRE
145 
146 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
147 //	gatheEnd <gatherLabel>
148 #ifndef INIT_SHADING
149 #define	GATHERENDEXPR_PRE	int	numRealVertices = currentShadingState->numRealVertices;				\
150 																									\
151 							for (;numRealVertices>0;numRealVertices--,tags++) {						\
152 								if (*tags) {														\
153 									(*tags)--;														\
154 									if (*tags == 0) {												\
155 										numActive++;												\
156 										numPassive--;												\
157 									}																\
158 								}																	\
159 							}																		\
160 																									\
161 							lastGather->numMisses	=	0;											\
162 							lastGather->remainingSamples--;											\
163 							if (lastGather->remainingSamples > 0) {									\
164 								jmp(argument(0));													\
165 							} else {																\
166 								delete lastGather;													\
167 							}
168 
169 #else
170 #define GATHERENDEXPR_PRE
171 #endif
172 
173 DEFOPCODE(GatherEnd	,"gatherEnd"	,1,	GATHERENDEXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,0)
174 
175 #undef GATHERENDEXPR_PRE
176 
177