1 #ifdef _WIN32
2 #include "windows.h"
3 #endif
4
5 #include "stdio.h"
6
7 #include "GL/gl.h"
8 #include "vector.h"
9 #include "quaternion.h"
10 #include "cmc.h"
11 #include "3dobject.h"
12 #include "piece3dobject.h"
13
14 #include "myglutaux.h"
15
Piece3DObject()16 Piece3DObject::Piece3DObject() : C3DObject()
17 {
18 shdw_npuntos_0=0;
19 shdw_ncaras_0=0;
20 shdw_puntos_0=0;
21 shdw_caras_0=0;
22 shdw_npuntos_90=0;
23 shdw_ncaras_90=0;
24 shdw_puntos_90=0;
25 shdw_caras_90=0;
26 shdw_npuntos_180=0;
27 shdw_ncaras_180=0;
28 shdw_puntos_180=0;
29 shdw_caras_180=0;
30 shdw_npuntos_270=0;
31 shdw_ncaras_270=0;
32 shdw_puntos_270=0;
33 shdw_caras_270=0;
34 shdw_npuntos_dynamic=0;
35 shdw_ncaras_dynamic=0;
36 shdw_puntos_dynamic=0;
37 shdw_caras_dynamic=0;
38 } /* Piece3DObject::Piece3DObject */
39
40
Piece3DObject(char * file,char * texturedir)41 Piece3DObject::Piece3DObject(char *file,char *texturedir) : C3DObject(file,texturedir)
42 {
43 shdw_npuntos_0=0;
44 shdw_ncaras_0=0;
45 shdw_puntos_0=0;
46 shdw_caras_0=0;
47 shdw_npuntos_90=0;
48 shdw_ncaras_90=0;
49 shdw_puntos_90=0;
50 shdw_caras_90=0;
51 shdw_npuntos_180=0;
52 shdw_ncaras_180=0;
53 shdw_puntos_180=0;
54 shdw_caras_180=0;
55 shdw_npuntos_270=0;
56 shdw_ncaras_270=0;
57 shdw_puntos_270=0;
58 shdw_caras_270=0;
59 shdw_npuntos_dynamic=0;
60 shdw_ncaras_dynamic=0;
61 shdw_puntos_dynamic=0;
62 shdw_caras_dynamic=0;
63 } /* Piece3DObject::Piece3DObject */
64
65
~Piece3DObject()66 Piece3DObject::~Piece3DObject()
67 {
68 delete shdw_puntos_0;
69 delete shdw_caras_0;
70 shdw_puntos_0=0;
71 shdw_caras_0=0;
72 delete shdw_puntos_90;
73 delete shdw_caras_90;
74 shdw_puntos_90=0;
75 shdw_caras_90=0;
76 delete shdw_puntos_180;
77 delete shdw_caras_180;
78 shdw_puntos_180=0;
79 shdw_caras_180=0;
80 delete shdw_puntos_270;
81 delete shdw_caras_270;
82 shdw_puntos_270=0;
83 shdw_caras_270=0;
84 delete shdw_puntos_dynamic;
85 delete shdw_caras_dynamic;
86 shdw_puntos_dynamic=0;
87 shdw_caras_dynamic=0;
88 } /* Piece3DObject::~Piece3DObject */
89
90
DrawShadow(int angle,Vector light,float r,float g,float b,float a)91 void Piece3DObject::DrawShadow(int angle,Vector light,float r,float g,float b,float a)
92 {
93 int i;
94
95 /* Dibuja el objeto: */
96 glEnableClientState(GL_VERTEX_ARRAY);
97 glColor4f(r,g,b,a);
98 glNormal3f(0,1,0);
99
100 angle=angle%360;
101
102 if (a!=1){
103 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
104 glEnable(GL_BLEND);
105 } /* if */
106
107 switch(angle) {
108 case 0:
109 glVertexPointer(3,GL_FLOAT,0,shdw_puntos_0);
110 glBegin(GL_TRIANGLES);
111 for(i=0;i<shdw_ncaras_0;i++) {
112 glArrayElement(shdw_caras_0[i*3]);
113 glArrayElement(shdw_caras_0[i*3+1]);
114 glArrayElement(shdw_caras_0[i*3+2]);
115 } /* for */
116 glEnd();
117 break;
118 case 90:
119 glVertexPointer(3,GL_FLOAT,0,shdw_puntos_90);
120 glBegin(GL_TRIANGLES);
121 for(i=0;i<shdw_ncaras_90;i++) {
122 glArrayElement(shdw_caras_90[i*3]);
123 glArrayElement(shdw_caras_90[i*3+1]);
124 glArrayElement(shdw_caras_90[i*3+2]);
125 } /* for */
126 glEnd();
127 break;
128 case 180:
129 glVertexPointer(3,GL_FLOAT,0,shdw_puntos_180);
130 glBegin(GL_TRIANGLES);
131 for(i=0;i<shdw_ncaras_180;i++) {
132 glArrayElement(shdw_caras_180[i*3]);
133 glArrayElement(shdw_caras_180[i*3+1]);
134 glArrayElement(shdw_caras_180[i*3+2]);
135 } /* for */
136 glEnd();
137 break;
138 case 270:
139 glVertexPointer(3,GL_FLOAT,0,shdw_puntos_270);
140 glBegin(GL_TRIANGLES);
141 for(i=0;i<shdw_ncaras_270;i++) {
142 glArrayElement(shdw_caras_270[i*3]);
143 glArrayElement(shdw_caras_270[i*3+1]);
144 glArrayElement(shdw_caras_270[i*3+2]);
145 } /* for */
146 glEnd();
147 break;
148 default:
149 ComputeDynamicShadow(angle,light);
150
151 glVertexPointer(3,GL_FLOAT,0,shdw_puntos_dynamic);
152 glBegin(GL_TRIANGLES);
153 for(i=0;i<shdw_ncaras_dynamic;i++) {
154 glArrayElement(shdw_caras_dynamic[i*3]);
155 glArrayElement(shdw_caras_dynamic[i*3+1]);
156 glArrayElement(shdw_caras_dynamic[i*3+2]);
157 } /* for */
158 glEnd();
159 break;
160 } /* switch */
161
162 if (a!=1) glDisable(GL_BLEND);
163 } /* Piece3DObject::DraqwShadow */
164
165
ComputeShadow(int angle,Vector light,int * np,int * nc,float ** p,int ** c,CMC * cmc)166 void Piece3DObject::ComputeShadow(int angle,Vector light,int *np,int *nc,float **p,int **c,CMC *cmc)
167 {
168 int i;
169 int pry_npuntos;
170 float *pry_puntos;
171 int *pry_caras,pry_ncaras;
172 float plane[4];
173 float l[4];
174 float v[3],w[3],n[3],value;
175 int shdw_ncaras;
176
177 angle=angle%360;
178
179 plane[0]=0;
180 plane[1]=0;
181 plane[2]=1;
182 plane[3]=0;
183
184
185 /* Rotar la luz: */
186 {
187 float lv[4]={float(light.x),float(light.y),float(light.z),1};
188 float axis[4]={0,0,1,1};
189 float m[16]={1,0,0,0,
190 0,1,0,0,
191 0,0,1,0,
192 0,0,0,1};
193 Quaternion q2;
194
195 q2.from_axis_angle(axis,float((-angle*3.14592f)/180));
196 q2.to_matrix(m);
197
198 ApplyMatrix(lv,m,l);
199 }
200
201 pry_npuntos=npuntos;
202 pry_puntos=new float[npuntos*3];
203 /* Proyectar TODOS los tri�ngulos sobre el plano Z: */
204 {
205 float p[3],tmp[3];
206
207 for(i=0;i<npuntos;i++) {
208 p[0]=puntos[i*3];
209 p[1]=puntos[i*3+1];
210 p[2]=puntos[i*3+2];
211 PlaneLineCollision(plane,p,l,tmp);
212
213 pry_puntos[i*3]=tmp[0];
214 pry_puntos[i*3+1]=tmp[1];
215 pry_puntos[i*3+2]=0;
216 } /* for */
217 }
218
219 /* Crear los tri�ngulos proyectadas: */
220 shdw_ncaras=0;
221 pry_ncaras=ncaras;
222 pry_caras=new int[ncaras*3];
223 for(i=0;i<ncaras;i++) {
224 /* Comprobar que el tri�ngulo es visible: */
225
226 v[0]=puntos[caras[i*3+1]*3]-puntos[caras[i*3]*3];;
227 v[1]=puntos[caras[i*3+1]*3+1]-puntos[caras[i*3]*3+1];
228 v[2]=puntos[caras[i*3+1]*3+2]-puntos[caras[i*3]*3+2];
229 w[0]=puntos[caras[i*3+2]*3]-puntos[caras[i*3+1]*3];
230 w[1]=puntos[caras[i*3+2]*3+1]-puntos[caras[i*3+1]*3+1];
231 w[2]=puntos[caras[i*3+2]*3+2]-puntos[caras[i*3+1]*3+2];
232 Normalf(v,w,n);
233
234 value=n[0]*l[0]+n[1]*l[1]+n[2]*l[2];
235 if (value>0) {
236 pry_caras[shdw_ncaras*3]=caras[i*3];
237 pry_caras[shdw_ncaras*3+1]=caras[i*3+1];
238 pry_caras[shdw_ncaras*3+2]=caras[i*3+2];
239 shdw_ncaras++;
240 } /* if */
241 } /* for */
242
243
244 /* Unir los tri�ngulos proyectados: */
245 /* ... */
246
247 /* Copiarlos a las variables del objeto: */
248 delete *p;
249 delete *c;
250 *p=0;
251 *c=0;
252 // shdw_puntos_dynamic=0;
253 // shdw_caras_dynamic=0;
254
255 *c=new int[shdw_ncaras*3];
256 for(i=0;i<shdw_ncaras*3;i++) (*c)[i]=pry_caras[i];
257 delete pry_caras;
258 pry_caras=0;
259 *nc=shdw_ncaras;
260 *np=pry_npuntos;
261 *p=pry_puntos;
262 cmc->set(*p,*np);
263
264 } /* Piece3DObject::ComputeShadow */
265
266
ComputeDynamicShadow(int angle,Vector light)267 void Piece3DObject::ComputeDynamicShadow(int angle,Vector light)
268 {
269 ComputeShadow(angle,light,&shdw_npuntos_dynamic,&shdw_ncaras_dynamic,
270 &shdw_puntos_dynamic,&shdw_caras_dynamic,&shdw_cmc_dynamic);
271 } /* Piece3DObject::ComputeDynamicShadow */
272
273
ComputeFixedShadows(Vector light)274 void Piece3DObject::ComputeFixedShadows(Vector light)
275 {
276 ComputeShadow(0,light,&shdw_npuntos_0,&shdw_ncaras_0,
277 &shdw_puntos_0,&shdw_caras_0,&shdw_cmc_0);
278 ComputeShadow(90,light,&shdw_npuntos_90,&shdw_ncaras_90,
279 &shdw_puntos_90,&shdw_caras_90,&shdw_cmc_90);
280 ComputeShadow(180,light,&shdw_npuntos_180,&shdw_ncaras_180,
281 &shdw_puntos_180,&shdw_caras_180,&shdw_cmc_180);
282 ComputeShadow(270,light,&shdw_npuntos_270,&shdw_ncaras_270,
283 &shdw_puntos_270,&shdw_caras_270,&shdw_cmc_270);
284 } /* Piece3DObject::ComputeShadow */
285