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