xref: /haiku/src/apps/glteapot/GLObject.cpp (revision cfc3fa87da824bdf593eb8b817a83b6376e77935)
1 /*
2  * Copyright 2008 Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Alexandre Deckner
7  *
8  */
9 
10 /*
11  * Original Be Sample source modified to use a quaternion for the object's orientation
12  */
13 
14 /*
15 	Copyright 1999, Be Incorporated.   All Rights Reserved.
16 	This file may be used under the terms of the Be Sample Code License.
17 */
18 
19 #include "GLObject.h"
20 #include <GL/gl.h>
21 #include <stdlib.h>
22 #include <InterfaceKit.h>
23 #include "glob.h"
24 
25 struct material {
26 	float ambient[3], diffuse[3], specular[3];
27 };
28 
29 float *colors[] = {NULL, white, yellow, blue, red, green};
30 
31 material materials[] = {
32 	// Null
33 	{
34 		{0.1745, 0.03175, 0.03175},
35 		{0.61424, 0.10136, 0.10136},
36 		{0.727811, 0.626959, 0.626959}
37 	},
38 	// White
39 	{
40 		{0.1745, 0.1745, 0.1745},
41 		{0.61424, 0.61424, 0.61424},
42 		{0.727811, 0.727811, 0.727811}
43 	},
44 	// Yellow
45 	{
46 		{0.1745, 0.1745, 0.03175},
47 		{0.61424, 0.61424, 0.10136},
48 		{0.727811, 0.727811, 0.626959}
49 	},
50 	// Blue
51 	{
52 		{0.03175, 0.03175, 0.1745},
53 		{0.10136, 0.10136, 0.61424},
54 		{0.626959, 0.626959, 0.727811}
55 	},
56 	// Red
57 	{
58 		{0.1745, 0.03175, 0.03175},
59 		{0.61424, 0.10136, 0.10136},
60 		{0.727811, 0.626959, 0.626959}
61 	},
62 	// Green
63 	{
64 		{0.03175, 0.1745, 0.03175},
65 		{0.10136, 0.61424, 0.10136},
66 		{0.626959, 0.727811, 0.626959}
67 	},
68 };
69 
70 #define USE_QUAD_STRIPS 1
71 
72 extern long setEvent(sem_id event);
73 
74 
75 GLObject::GLObject(ObjectView* ov)
76 	:
77 	x(0),
78 	y(0),
79 	z(-2.0),
80 	fRotation(0.0f, 0.0f, 0.0f, 1.0f),
81 	spinX(2),
82 	spinY(2),
83 	solidity(0),
84 	color(4),
85 	changed(false),
86 	fObjView(ov)
87 {
88 }
89 
90 
91 GLObject::~GLObject()
92 {
93 }
94 
95 
96 void
97 GLObject::MenuInvoked(BPoint point)
98 {
99 	BPopUpMenu* m = new BPopUpMenu("Object",false,false);
100 	BMenuItem* i;
101 
102 	int c = 1;
103 	m->AddItem(i = new BMenuItem("White",NULL));
104 	if (color == c++)
105 		i->SetMarked(true);
106 	m->AddItem(i = new BMenuItem("Yellow",NULL));
107 	if (color == c++)
108 		i->SetMarked(true);
109 	m->AddItem(i = new BMenuItem("Blue",NULL));
110 	if (color == c++)
111 		i->SetMarked(true);
112 	m->AddItem(i = new BMenuItem("Red",NULL));
113 	if (color == c++)
114 		i->SetMarked(true);
115 	m->AddItem(i = new BMenuItem("Green",NULL));
116 	if (color == c++)
117 		i->SetMarked(true);
118 	m->AddSeparatorItem();
119 
120 	c = 0;
121 	m->AddItem(i = new BMenuItem("Solid",NULL));
122 	if (solidity == c++)
123 		i->SetMarked(true);
124 	m->AddItem(i = new BMenuItem("Translucent",NULL));
125 	if (solidity == c++)
126 		i->SetMarked(true);
127 	m->AddItem(i = new BMenuItem("Transparent",NULL));
128 	if (solidity == c++)
129 		i->SetMarked(true);
130 
131 	i = m->Go(point);
132 	int32 index = m->IndexOf(i);
133 	delete m;
134 
135 	if (index < 5) {
136 		color = index+1;
137 	} else if (index > 5) {
138 		solidity = index-6;
139 	}
140 	changed = true;
141 	setEvent(fObjView->drawEvent);
142 }
143 
144 int
145 GLObject::Solidity() const
146 {
147 	return solidity;
148 }
149 
150 
151 bool
152 GLObject::SpinIt()
153 {
154 	bool c = changed;
155 	c = c || ((spinX != 0.0f) || (spinY != 0.0f));
156 
157 	if (c)
158 		RotateWorldSpace(spinY, spinX);
159 
160 	return c;
161 }
162 
163 
164 void
165 GLObject::Spin(float rx, float ry)
166 {
167 	spinX = rx;
168 	spinY = ry;
169 }
170 
171 
172 void
173 GLObject::RotateWorldSpace(float rx, float ry)
174 {
175 	fRotation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), 0.01f * rx) * fRotation;
176 	fRotation = Quaternion(Vector3(1.0f, 0.0f, 0.0f), 0.01f * ry) * fRotation;
177 	changed = true;
178 }
179 
180 
181 void
182 GLObject::Draw(bool forID, float IDcolor[])
183 {
184 	glPushMatrix();
185 		glTranslatef(x, y, z);
186 
187 		float mat[4][4];
188 		fRotation.toOpenGLMatrix(mat);
189 		glMultMatrixf((GLfloat*)mat);
190 
191 		if (forID) {
192 			glColor3fv(IDcolor);
193 		}
194 
195 		DoDrawing(forID);
196 
197 	glPopMatrix();
198 
199 	changed = false;
200 }
201 
202 
203 TriangleObject::TriangleObject(ObjectView* ov, char* filename)
204 	: 	GLObject(ov),
205 		fPoints(100,100),
206 		fTriangles(100,100),
207 		fQs(50,50)
208 {
209 	float maxp = 0;
210 	int numPt,numTri;
211 
212 	FILE* f = fopen(filename,"r");
213 	fscanf(f,"%d",&numPt);
214 //	printf("Points: %d\n",numPt);
215 	for (int i = 0; i < numPt; i++) {
216 		point p;
217 		fscanf(f,"%f %f %f %f %f %f",
218 			&p.x,
219 			&p.y,
220 			&p.z,
221 			&p.nx,
222 			&p.ny,
223 			&p.nz);
224 		if (fabs(p.x) > maxp)
225 			maxp = fabs(p.x);
226 		if (fabs(p.y) > maxp)
227 			maxp = fabs(p.y);
228 		if (fabs(p.z) > maxp)
229 			maxp = fabs(p.z);
230 		fPoints.add(p);
231 	}
232 
233 	for (int i = 0; i < fPoints.num_items; i++) {
234 		fPoints[i].x /= maxp;
235 		fPoints[i].y /= maxp;
236 		fPoints[i].z /= maxp;
237 	}
238 
239 	fscanf(f,"%d",&numTri);
240 //	printf("Triangles: %d\n",numTri);
241 	int tpts = 0;
242 	for (int i = 0; i < numTri; i++) {
243 		tri t;
244 		fscanf(f,"%d %d %d",
245 			&t.p1,
246 			&t.p2,
247 			&t.p3);
248 		fTriangles.add(t);
249 		tpts += 3;
250 	}
251 
252 	int qpts = 4;
253 	int qp[1024];
254 	quadStrip q;
255 	q.pts = qp;
256 	q.numpts = 4;
257 	q.pts[2] = fTriangles[0].p1;
258 	q.pts[0] = fTriangles[0].p2;
259 	q.pts[1] = fTriangles[0].p3;
260 	q.pts[3] = fTriangles[1].p3;
261 
262 	for (int i = 2; i < numTri; i += 2) {
263 		if ((fTriangles[i-1].p1 == fTriangles[i].p2) &&
264 			(fTriangles[i-1].p3 == fTriangles[i].p3)) {
265 			q.pts[q.numpts++] = fTriangles[i+1].p1;
266 			q.pts[q.numpts++] = fTriangles[i+1].p3;
267 			qpts+=2;
268 		} else {
269 			int *np = (int*)malloc(sizeof(int)*q.numpts);
270 			memcpy(np,qp,q.numpts*sizeof(int));
271 			quadStrip nqs;
272 			nqs.numpts = q.numpts;
273 			nqs.pts = np;
274 			fQs.add(nqs);
275 
276 			qpts += 4;
277 			q.numpts = 4;
278 			q.pts[2] = fTriangles[i].p1;
279 			q.pts[0] = fTriangles[i].p2;
280 			q.pts[1] = fTriangles[i].p3;
281 			q.pts[3] = fTriangles[i+1].p3;
282 		}
283 	}
284 
285 	int* np = (int*)malloc(sizeof(int)*q.numpts);
286 	memcpy(np,qp,q.numpts*sizeof(int));
287 	quadStrip nqs;
288 	nqs.numpts = q.numpts;
289 	nqs.pts = np;
290 	fQs.add(nqs);
291 
292 	fclose(f);
293 }
294 
295 
296 TriangleObject::~TriangleObject()
297 {
298 	for (int i = 0; i < fQs.num_items; i++) {
299 		free(fQs[i].pts);
300 	}
301 }
302 
303 
304 void
305 TriangleObject::DoDrawing(bool forID)
306 {
307 	if (!forID) {
308 		float c[3][4];
309 		c[0][0] = materials[color].ambient[0];
310 		c[0][1] = materials[color].ambient[1];
311 		c[0][2] = materials[color].ambient[2];
312 		c[1][0] = materials[color].diffuse[0];
313 		c[1][1] = materials[color].diffuse[1];
314 		c[1][2] = materials[color].diffuse[2];
315 		c[2][0] = materials[color].specular[0];
316 		c[2][1] = materials[color].specular[1];
317 		c[2][2] = materials[color].specular[2];
318 
319 		float alpha = 1;
320 		if (solidity == 0)
321 			alpha = 1.0;
322 		else if (solidity == 1)
323 			alpha = 0.95;
324 		else if (solidity == 2)
325 			alpha = 0.6;
326 		c[0][3] = c[1][3] = c[2][3] = alpha;
327 		if (solidity != 0) {
328 			glBlendFunc(GL_SRC_ALPHA,GL_ONE);
329 			glEnable(GL_BLEND);
330 			glDepthMask(GL_FALSE);
331 			glDisable(GL_CULL_FACE);
332 		} else {
333 			glDisable(GL_BLEND);
334 			glDepthMask(GL_TRUE);
335 		}
336 		glMaterialfv(GL_FRONT, GL_AMBIENT, c[0]);
337 		glMaterialfv(GL_FRONT, GL_DIFFUSE, c[1]);
338 		glMaterialfv(GL_FRONT, GL_SPECULAR, c[2]);
339 	} else {
340 		glDisable(GL_BLEND);
341 		glDepthMask(GL_TRUE);
342 	}
343 
344 #if USE_QUAD_STRIPS
345 		for (int i = 0; i < fQs.num_items; i++) {
346  			glBegin(GL_QUAD_STRIP);
347 			for (int j = 0; j < fQs[i].numpts; j++) {
348  				glNormal3f(
349 					fPoints[fQs[i].pts[j]].nx,
350 					fPoints[fQs[i].pts[j]].ny,
351 					fPoints[fQs[i].pts[j]].nz
352 				);
353  				glVertex3f(
354 					fPoints[fQs[i].pts[j]].x,
355 					fPoints[fQs[i].pts[j]].y,
356 					fPoints[fQs[i].pts[j]].z
357 				);
358 			}
359 			glEnd();
360 		}
361 #else
362  		glBegin(GL_TRIANGLES);
363 		for (int i = 0; i < fTriangles.num_items; i++) {
364 			int v3 = fTriangles[i].p1;
365 			int v1 = fTriangles[i].p2;
366 			int v2 = fTriangles[i].p3;
367  	  		glNormal3f(
368 				fPoints[v1].nx,
369 				fPoints[v1].ny,
370 				fPoints[v1].nz
371 			);
372  			glVertex3f(
373 				fPoints[v1].x,
374 				fPoints[v1].y,
375 				fPoints[v1].z
376 			);
377  			glNormal3f(
378 				fPoints[v2].nx,
379 				fPoints[v2].ny,
380 				fPoints[v2].nz
381 			);
382  			glVertex3f(
383 				fPoints[v2].x,
384 				fPoints[v2].y,
385 				fPoints[v2].z
386 			);
387  			glNormal3f(
388 				fPoints[v3].nx,
389 				fPoints[v3].ny,
390 				fPoints[v3].nz
391 			);
392 			glVertex3f(
393 				fPoints[v3].x,
394 				fPoints[v3].y,
395 				fPoints[v3].z
396 			);
397 		}
398 		glEnd();
399  #endif
400 }
401 
402