From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/glx/bubble3d.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 hacks/glx/bubble3d.c (limited to 'hacks/glx/bubble3d.c') diff --git a/hacks/glx/bubble3d.c b/hacks/glx/bubble3d.c new file mode 100644 index 0000000..9cd2afc --- /dev/null +++ b/hacks/glx/bubble3d.c @@ -0,0 +1,281 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* bubble3d.c - 3D bubbles */ + +#if 0 +static const char sccsid[] = "@(#)bubble3d.c 4.11 98/06/16 xlockmore"; +#endif + +/*- + * BUBBLE3D (C) 1998 Richard W.M. Jones. + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * 16-Jun-98: Written. + * + * bubble.c: This code is responsible for creating and managing + * bubbles over their lifetime. + * The bubbles may be drawn inside out. + */ + +#include "bubble3d.h" + +typedef struct bubble { + GLfloat *contributions; /* List of contributions from each + * nudge to each vertex. This list has + * length nr_vertices * nr_nudge_axes. + */ + GLfloat x, y, z; /* (x,y,z) location of the bubble. */ + GLfloat scale; /* Scaling factor applied to bubble. */ + GLfloat y_incr, scale_incr; /* Change in y and scale each frame. */ + GLfloat rotx, roty, rotz; /* Current rotation. */ + GLfloat rotx_incr, roty_incr, rotz_incr; /* Amount by which we increase + * rotation each step. + */ + GLfloat *nudge_angle; /* Current angle (radians) of each + * nudge. This list has length nr_nudge_axes. + */ + GLfloat *nudge_angle_incr; /* Amount by which we increase each nudge + * angle in each frame. + */ + GLfloat color[4]; +} bubble; + +/* Should be taken care of already... but just in case */ +#if !defined( __GNUC__ ) && !defined(__cplusplus) && !defined(c_plusplus) +#undef inline +#define inline /* */ +#endif +static inline void +normalize(GLfloat v[3]) +{ + GLfloat d = (GLfloat) sqrt((double) (v[0] * v[0] + v[1] * v[1] + + v[2] * v[2])); + + if (d != 0) { + v[0] /= d; + v[1] /= d; + v[2] /= d; + } else { + v[0] = v[1] = v[2] = 0; + } +} + +static inline GLfloat +dotprod(GLfloat * v1, GLfloat * v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +static inline GLfloat +max(GLfloat a, GLfloat b) +{ + return a > b ? a : b; +} + +/* Create a new bubble. */ +void * +glb_bubble_new(glb_data *d, GLfloat x, GLfloat y, GLfloat z, GLfloat scale, + GLfloat y_incr, GLfloat scale_incr) +{ + int i, j; + + /* GLfloat axes [glb_config.nr_nudge_axes][3]; */ + GLfloat axes[5][3]; /* HARD CODED for SunCC */ + int nr_vertices; + glb_vertex *vertices = glb_sphere_get_vertices(d, &nr_vertices); + + bubble *b = (bubble *) malloc(sizeof *b); + + if (b == 0) + return 0; + + if (glb_config.bubble_colour[0] == -1.0) { + b->color[0] = ((float) (NRAND(100)) / 100.0); + b->color[1] = ((float) (NRAND(100)) / 100.0); + b->color[2] = ((float) (NRAND(100)) / 100.0); + } else { + b->color[0] = glb_config.bubble_colour[0]; + b->color[1] = glb_config.bubble_colour[1]; + b->color[2] = glb_config.bubble_colour[2]; + } + b->color[3] = glb_config.bubble_colour[3]; + + + b->contributions = (GLfloat *) malloc(sizeof (GLfloat) * nr_vertices * + glb_config.nr_nudge_axes); + if (b->contributions == 0) { + (void) free((void *) b); + return 0; + } + b->nudge_angle = (GLfloat *) malloc(sizeof (GLfloat) * glb_config.nr_nudge_axes); + if (b->nudge_angle == 0) { + (void) free((void *) b->contributions); + (void) free((void *) b); + return 0; + } + b->nudge_angle_incr = (GLfloat *) malloc(sizeof (GLfloat) * glb_config.nr_nudge_axes); + if (b->nudge_angle_incr == 0) { + (void) free((void *) b->nudge_angle); + (void) free((void *) b->contributions); + (void) free((void *) b); + return 0; + } + /* Initialize primitive elements. */ + b->x = x; + b->y = y; + b->z = z; + b->scale = scale; + b->y_incr = y_incr; + b->scale_incr = scale_incr; + b->rotx = b->roty = b->rotz = 0; + b->rotx_incr = glb_drand() * glb_config.rotation_factor * 2 + - glb_config.rotation_factor; + b->roty_incr = glb_drand() * glb_config.rotation_factor * 2 + - glb_config.rotation_factor; + b->rotz_incr = glb_drand() * glb_config.rotation_factor * 2 + - glb_config.rotation_factor; + + /* Initialize the nudge angle arrays. */ + for (i = 0; i < glb_config.nr_nudge_axes; ++i) { + b->nudge_angle[i] = 0; + b->nudge_angle_incr[i] = glb_drand() * glb_config.nudge_angle_factor; + } + + /* Choose some random nudge axes. */ + for (i = 0; i < glb_config.nr_nudge_axes; ++i) { + axes[i][0] = glb_drand() * 2 - 1; + axes[i][1] = glb_drand() * 2 - 1; + axes[i][2] = glb_drand() * 2 - 1; + normalize(axes[i]); + } + + /* Calculate the contribution that each nudge axis has on each vertex. */ + for (i = 0; i < nr_vertices; ++i) + for (j = 0; j < glb_config.nr_nudge_axes; ++j) + b->contributions[i * glb_config.nr_nudge_axes + j] + = max(0, dotprod(vertices[i], axes[j])); + + return (void *) b; +} + +/* Delete a bubble and free up all memory. */ +void +glb_bubble_delete(void *bb) +{ + bubble *b = (bubble *) bb; + + if (b != NULL) { + if (b->nudge_angle_incr) { + (void) free((void *) b->nudge_angle_incr); + b->nudge_angle_incr = NULL; + } + if (b->nudge_angle) { + (void) free((void *) b->nudge_angle); + b->nudge_angle = NULL; + } + if (b->contributions) { + (void) free((void *) b->contributions); + b->contributions = NULL; + } + (void) free((void *) b); + b = NULL; + } +} + +/* Rotate and wobble a bubble by a single step. */ +void +glb_bubble_step(void *bb) +{ + int i; + bubble *b = (bubble *) bb; + + /* Update the rotation. */ + b->rotx += b->rotx_incr; + b->roty += b->roty_incr; + b->rotz += b->rotz_incr; + + /* Update the nudge angles. */ + for (i = 0; i < glb_config.nr_nudge_axes; ++i) + b->nudge_angle[i] += b->nudge_angle_incr[i]; + + /* Move it upwards & outwards. */ + b->y += b->y_incr; + b->scale += b->scale_incr; +} + +/* Draw a bubble. */ +void +glb_bubble_draw(glb_data *d, void *bb) +{ + int i, j; + bubble *b = (bubble *) bb; + int nr_vertices; + glb_vertex *vertices = glb_sphere_get_vertices(d, &nr_vertices); + int nr_triangles; + glb_triangle *triangles = glb_sphere_get_triangles(d, &nr_triangles); + glb_vertex *new_vertices; + + new_vertices = (glb_vertex *) malloc(sizeof (glb_vertex) * nr_vertices); + /* Calculate the vertices of this bubble, factoring in each nudge axis. */ + for (i = 0; i < nr_vertices; ++i) { + GLfloat s = 0; + + for (j = 0; j < glb_config.nr_nudge_axes; ++j) + s += ((GLfloat) cos((double) (b->nudge_angle[j])) * + glb_config.nudge_factor - glb_config.nudge_factor / 2) * + b->contributions[i * glb_config.nr_nudge_axes + j]; + + new_vertices[i][0] = vertices[i][0] * (s + 1); + new_vertices[i][1] = vertices[i][1] * (s + 1); + new_vertices[i][2] = vertices[i][2] * (s + 1); + } + + glPushMatrix(); + + /* Apply translation, rotation and scalings. */ + glTranslatef(b->x, b->y, b->z); + + glRotatef(b->rotx, 1, 0, 0); + glRotatef(b->roty, 0, 1, 0); + glRotatef(b->rotz, 0, 0, 1); + + glScalef(b->scale, b->scale, b->scale); + + /* Draw the bubble. */ + glFrontFace(GL_CW); + glBegin(GL_TRIANGLES); + + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, b->color); + + for (i = 0; i < nr_triangles; ++i) { + glNormal3fv(new_vertices[triangles[i][0]]); + glVertex3fv(new_vertices[triangles[i][0]]); + glNormal3fv(new_vertices[triangles[i][1]]); + glVertex3fv(new_vertices[triangles[i][1]]); + glNormal3fv(new_vertices[triangles[i][2]]); + glVertex3fv(new_vertices[triangles[i][2]]); + } + glEnd(); + glPopMatrix(); + (void) free((void *) new_vertices); + glb_config.polygon_count += nr_triangles; +} + +/* Return y value. */ +GLfloat +glb_bubble_get_y(void *bb) +{ + bubble *b = (bubble *) bb; + + return b->y; +} -- cgit v1.2.3-55-g7522