Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Graphics/geometry.cpp')
-rw-r--r--Source/Graphics/geometry.cpp809
1 files changed, 809 insertions, 0 deletions
diff --git a/Source/Graphics/geometry.cpp b/Source/Graphics/geometry.cpp
new file mode 100644
index 00000000..fa699d7c
--- /dev/null
+++ b/Source/Graphics/geometry.cpp
@@ -0,0 +1,809 @@
+//-----------------------------------------------------------------------------
+// Name: geometry.cpp
+// Author: Freeglut
+// License: X-Consortium license
+// Description: Data and utility functions for rendering several useful
+// geometric shapes. This code is a modified version of the
+// code found in "freeglut_teapot.c" and "freeglut_geometry.c",
+// which is part of the open source project, Freeglut.
+// http://freeglut.sourceforge.net/
+//
+// Modified by Wolfire Games LLC for use in the project
+// Overgrowth.
+//
+// ----------------------------------------------------------------------------
+// Freeglut Copyright
+// ------------------
+//
+// Freeglut code without an explicit copyright is covered by the following
+// copyright :
+//
+// Copyright(c) 1999 - 2000 Pawel W.Olszta.All Rights Reserved.
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this softwareand associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
+// copies or substantial portions of the Software.
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL
+// PAWEL W.OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Except as contained in this notice, the name of Pawel W.Olszta shall not be
+// used in advertising or otherwise to promote the sale, use or other dealings
+// in this Software without prior written authorization from Pawel W.Olszta.
+// ---------------------------------------------------------------------------
+/*
+ * freeglut_geometry.c
+ *
+ * Freeglut geometry rendering methods.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Creation date: Fri Dec 3 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * freeglut_teapot.c
+ *
+ * Teapot(tm) rendering code.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Creation date: Fri Dec 24 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Original teapot code copyright follows:
+ */
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ *
+ * ALL RIGHTS RESERVED
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that
+ * both the copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Silicon
+ * Graphics, Inc. not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
+ * "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
+ * OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
+ * EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
+ * ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
+ * INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
+ * SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
+ * NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
+ * OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ *
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227f.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer
+ * Software clause at DFARS 252.227f-7013 and/or in similar or
+ * successor clauses in the FAR or the DOD or NASA FAR
+ * Supplement. Unpublished-- rights reserved under the copyright
+ * laws of the United States. Contractor/manufacturer is Silicon
+ * Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
+ * 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+//
+// The following functions are defined here:
+//
+// void renderWireTeapot(GLdouble size);
+// void renderSolidTeapot(GLdouble size);
+// void renderWireCube(GLdouble size);
+// void renderSolidCube(GLdouble size);
+// void renderWireSphere(GLdouble radius, GLint slices, GLint stacks);
+// void renderSolidSphere(GLdouble radius, GLint slices, GLint stacks);
+// void renderWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+// void renderSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+// void renderWireCylinder(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+// void renderSolidCyliner(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+// void renderWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+// void renderSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+// void renderWireDodecahedron(void);
+// void renderSolidDodecahedron(void);
+// void renderWireOctahedron(void);
+// void renderSolidOctahedron(void);
+// void renderWireTetrahedron(void);
+// void renderSolidTetrahedron(void);
+// void renderWireIcosahedron(void);
+// void renderSolidIcosahedron(void);
+// void renderWireSierpinskiSponge(int num_levels, GLdouble offset[3], GLdouble scale);
+// void renderSolidSierpinskiSponge(int num_levels, GLdouble offset[3], GLdouble scale);
+//-----------------------------------------------------------------------------
+
+#include <Graphics/geometry.h>
+#include <Graphics/graphics.h>
+
+#include <Math/vec3math.h>
+#include <Memory/allocation.h>
+
+static void circleTable(double **sint,double **cost,const int n);
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * Compute lookup table of cos and sin values forming a cirle
+ *
+ * Notes:
+ * It is the responsibility of the caller to free these tables
+ * The size of the table is (n+1) to form a connected loop
+ * The last entry is exactly the same as the first
+ * The sign of n can be flipped to get the reverse loop
+ */
+
+static void circleTable(double **sint,double **cost,const int n)
+{
+ int i;
+
+ /* Table size, the sign of n flips the circle direction */
+
+ const int size = abs(n);
+
+ /* Determine the angle between samples */
+
+ const double angle = 2*PI/(double)n;
+
+ /* Allocate memory for n samples, plus duplicate of first entry at the end */
+
+ *sint = (double *) calloc(sizeof(double), size+1);
+ *cost = (double *) calloc(sizeof(double), size+1);
+
+ /* Bail out if memory allocation fails, fgError never returns */
+
+ if (!(*sint) || !(*cost))
+ {
+ OG_FREE(*sint);
+ *sint = NULL;
+ OG_FREE(*cost);
+ *cost = NULL;
+ FatalError("Error", "Failed to allocate memory in circleTable");
+ }
+
+ /* Compute cos and sin around the circle */
+
+ for (i=0; i<size; i++)
+ {
+ (*sint)[i] = sin(angle*i);
+ (*cost)[i] = cos(angle*i);
+ }
+
+ /* Last sample is duplicate of the first */
+
+ (*sint)[size] = (*sint)[0];
+ (*cost)[size] = (*cost)[0];
+}
+
+void GetWireCylinderVertArray(GLint slices, std::vector<vec3> &data)
+{
+ // x right, y up, z forward
+ float rotationStep = (2.0f*PI_f)/(float)slices;
+ float radius = 0.5f;
+ float halfheight = 0.5f;
+
+ vec3 centerTop( 0,halfheight,0 );
+ vec3 centerBottom( 0, -halfheight,0);
+
+ data.reserve( slices * 2 * 10 );
+
+ for( int i = 0; i < slices; i++ )
+ {
+ float rotation1 = i*rotationStep;
+ float rotation2 = (i+1)*rotationStep;
+
+ vec3 offset1(radius*(cos(rotation1)-sin(rotation1)), 0.0f, radius*(sin(rotation1)+cos(rotation1)));
+ vec3 pointTop1 = offset1+centerTop;
+ vec3 pointBottom1 = offset1+centerBottom;
+
+ vec3 offset2(radius*(cos(rotation2)-sin(rotation2)), 0.0f, radius*(sin(rotation2)+cos(rotation2)));
+ vec3 pointTop2 = offset2+centerTop;
+ vec3 pointBottom2 = offset2+centerBottom;
+
+ data.push_back( centerTop );
+ data.push_back( pointTop1 );
+
+ data.push_back( pointTop1 );
+ data.push_back( pointTop2 );
+
+ data.push_back( pointTop1 );
+ data.push_back( pointBottom1 );
+
+ data.push_back( pointBottom1 );
+ data.push_back( pointBottom2 );
+
+ data.push_back( pointBottom1 );
+ data.push_back( centerBottom );
+ }
+}
+
+void GetWireBoxVertArray( std::vector<vec3> &data )
+{
+ vec3 corners[] =
+ {
+ //Upper four corners
+ vec3( 0.5f, 0.5f, 0.5f ),
+ vec3( 0.5f, 0.5f, -0.5f ),
+ vec3( -0.5f, 0.5f, -0.5f ),
+ vec3( -0.5f, 0.5f, 0.5f ),
+
+ //Lower four corners
+ vec3( 0.5f, -0.5f, 0.5f ),
+ vec3( 0.5f, -0.5f, -0.5f ),
+ vec3( -0.5f, -0.5f, -0.5f ),
+ vec3( -0.5f, -0.5f, 0.5f ),
+ };
+
+ //We start with spinning around the top and the bottom.
+ for( int i = 1; i <= 4; i++ )
+ {
+ int prev_index = i - 1;
+ int cur_index = i % 4;
+
+ data.push_back( corners[prev_index] );
+ data.push_back( corners[cur_index] );
+ }
+
+ for( int i = 1; i <= 4; i++ )
+ {
+ int prev_index = 4 + i - 1;
+ int cur_index = 4 + i % 4;
+
+ data.push_back( corners[prev_index] );
+ data.push_back( corners[cur_index] );
+ }
+
+ //Then we match each bottom point with the one right above.
+ for( int i = 0; i < 4; i++ )
+ {
+ data.push_back( corners[i] );
+ data.push_back( corners[i+4] );
+ }
+}
+
+/*
+ * Draws a solid sphere
+ */
+void renderSolidSphere(GLdouble radius, GLint slices, GLint stacks)
+{
+ int i,j;
+
+ /* Adjust z and radius as stacks are drawn. */
+
+ double z0,z1;
+ double r0,r1;
+
+ /* Pre-computed circle */
+
+ double *sint1,*cost1;
+ double *sint2,*cost2;
+ circleTable(&sint1,&cost1,-slices);
+ circleTable(&sint2,&cost2,stacks*2);
+
+ /* The top stack is covered with a triangle fan */
+
+ z0 = 1.0f;
+ z1 = cost2[1];
+ r0 = 0.0f;
+ r1 = sint2[1];
+
+ glBegin(GL_TRIANGLE_FAN);
+
+ glNormal3d(0,0,1);
+ glVertex3d(0,0,radius);
+
+ for (j=slices; j>=0; j--)
+ {
+ glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 );
+ glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
+ }
+
+ glEnd();
+
+ /* Cover each stack with a quad strip, except the top and bottom stacks */
+
+ for( i=1; i<stacks-1; i++ )
+ {
+ z0 = z1; z1 = cost2[i+1];
+ r0 = r1; r1 = sint2[i+1];
+
+ glBegin(GL_QUAD_STRIP);
+
+ for(j=0; j<=slices; j++)
+ {
+ glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 );
+ glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
+ glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 );
+ glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
+ }
+
+ glEnd();
+ }
+
+ /* The bottom stack is covered with a triangle fan */
+
+ z0 = z1;
+ r0 = r1;
+
+ glBegin(GL_TRIANGLE_FAN);
+
+ glNormal3d(0,0,-1);
+ glVertex3d(0,0,-radius);
+
+ for (j=0; j<=slices; j++)
+ {
+ glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 );
+ glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
+ }
+
+ glEnd();
+
+ /* Release sin and cos tables */
+
+ OG_FREE(sint1);
+ OG_FREE(cost1);
+ OG_FREE(sint2);
+ OG_FREE(cost2);
+}
+
+// Get interleaved vert array (3 verts) for GL_LINES
+void GetWireSphereVertArray(GLdouble radius, GLint slices, GLint stacks, std::vector<float> &data) {
+ double r,x,y,z;
+ double *sint1,*cost1;
+ double *sint2,*cost2;
+ circleTable(&sint1,&cost1,-slices );
+ circleTable(&sint2,&cost2, stacks*2);
+ for (int i=1; i<stacks; i++) {
+ z = cost2[i];
+ r = sint2[i];
+ for(int j=0; j<=slices; j++){
+ x = cost1[j];
+ y = sint1[j];
+ //data.push_back((float)x);
+ //data.push_back((float)y);
+ //data.push_back((float)z);
+ data.push_back((float)(x*r*radius));
+ data.push_back((float)(y*r*radius));
+ data.push_back((float)(z*radius));
+ if(j!=0 && j!=slices){
+ //data.push_back((float)x);
+ //data.push_back((float)y);
+ //data.push_back((float)z);
+ data.push_back((float)(x*r*radius));
+ data.push_back((float)(y*r*radius));
+ data.push_back((float)(z*radius));
+ }
+ }
+ }
+ for (int i=0; i<slices; i++) {
+ for(int j=0; j<=stacks; j++){
+ x = cost1[i]*sint2[j];
+ y = sint1[i]*sint2[j];
+ z = cost2[j];
+ //data.push_back((float)x);
+ //data.push_back((float)y);
+ //data.push_back((float)z);
+ data.push_back((float)(x*radius));
+ data.push_back((float)(y*radius));
+ data.push_back((float)(z*radius));
+ if(j!=0 && j!=stacks){
+ //data.push_back((float)x);
+ //data.push_back((float)y);
+ //data.push_back((float)z);
+ data.push_back((float)(x*radius));
+ data.push_back((float)(y*radius));
+ data.push_back((float)(z*radius));
+ }
+ }
+ }
+ OG_FREE(sint1);
+ OG_FREE(cost1);
+ OG_FREE(sint2);
+ OG_FREE(cost2);
+}
+
+void GetUnitBoxVertArray(std::vector<float> &verts)
+{
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(-0.5f); verts.push_back(-0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(-0.5f);
+ verts.push_back(-0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+ verts.push_back(0.5f); verts.push_back(0.5f); verts.push_back(0.5f);
+}
+
+void GetUnitBoxVertArray(std::vector<float> &verts, std::vector<unsigned> &faces)
+{
+
+ verts.push_back(0.500000);
+ verts.push_back(-0.500000);
+ verts.push_back(-0.500000);
+
+ verts.push_back(0.500000);
+ verts.push_back(-0.500000);
+ verts.push_back(0.500000);
+
+ verts.push_back(-0.500000);
+ verts.push_back(-0.500000);
+ verts.push_back(0.500000);
+
+ verts.push_back(-0.500000);
+ verts.push_back(-0.500000);
+ verts.push_back(-0.500000);
+
+ verts.push_back(0.500000);
+ verts.push_back(0.500000);
+ verts.push_back(-0.500000);
+
+ verts.push_back(0.500000);
+ verts.push_back(0.500000);
+ verts.push_back(0.500000);
+
+ verts.push_back(-0.500000);
+ verts.push_back(0.500000);
+ verts.push_back(0.500000);
+
+ verts.push_back(-0.500000);
+ verts.push_back(0.500000);
+ verts.push_back(-0.500000);
+
+ faces.push_back(1-1);
+ faces.push_back(2-1);
+ faces.push_back(4-1);
+ faces.push_back(5-1);
+ faces.push_back(8-1);
+ faces.push_back(6-1);
+ faces.push_back(1-1);
+ faces.push_back(5-1);
+ faces.push_back(2-1);
+ faces.push_back(2-1);
+ faces.push_back(6-1);
+ faces.push_back(3-1);
+ faces.push_back(3-1);
+ faces.push_back(7-1);
+ faces.push_back(4-1);
+ faces.push_back(5-1);
+ faces.push_back(1-1);
+ faces.push_back(8-1);
+ faces.push_back(2-1);
+ faces.push_back(3-1);
+ faces.push_back(4-1);
+ faces.push_back(8-1);
+ faces.push_back(7-1);
+ faces.push_back(6-1);
+ faces.push_back(5-1);
+ faces.push_back(6-1);
+ faces.push_back(2-1);
+ faces.push_back(6-1);
+ faces.push_back(7-1);
+ faces.push_back(3-1);
+ faces.push_back(7-1);
+ faces.push_back(8-1);
+ faces.push_back(4-1);
+ faces.push_back(1-1);
+ faces.push_back(4-1);
+ faces.push_back(8-1);
+}
+
+/*
+ * Draws a solid cylinder
+ */
+void renderSolidCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
+{
+ int i,j;
+
+ /* Step in z and radius as stacks are drawn. */
+
+
+ double z0,z1;
+ const double zStep = height/stacks;
+
+ /* Pre-computed circle */
+
+ double *sint,*cost;
+ circleTable(&sint,&cost,-slices);
+
+ /* Cover the base and top */
+
+ glBegin(GL_TRIANGLE_FAN);
+ glNormal3d(0.0f, 0.0f, -1.0f );
+ glVertex3d(0.0f, 0.0f, -height/2 );
+ for (j=0; j<=slices; j++)
+ glVertex3d(cost[j]*radius, sint[j]*radius, -height/2);
+ glEnd();
+
+ glBegin(GL_TRIANGLE_FAN);
+ glNormal3d(0.0f, 0.0f, 1.0f );
+ glVertex3d(0.0f, 0.0f, height/2);
+ for (j=slices; j>=0; j--)
+ glVertex3d(cost[j]*radius, sint[j]*radius, height/2);
+ glEnd();
+
+ /* Do the stacks */
+
+ z0 = -height/2;
+ z1 = zStep-height/2;
+
+ for (i=1; i<=stacks; i++)
+ {
+ if (i==stacks)
+ z1 = height/2;
+
+ glBegin(GL_QUAD_STRIP);
+ for (j=0; j<=slices; j++ )
+ {
+ glNormal3d(cost[j], sint[j], 0.0f );
+ glVertex3d(cost[j]*radius, sint[j]*radius, z0 );
+ glVertex3d(cost[j]*radius, sint[j]*radius, z1 );
+ }
+ glEnd();
+
+ z0 = z1; z1 += zStep;
+ }
+
+ /* Release sin and cos tables */
+
+ OG_FREE(sint);
+ OG_FREE(cost);
+}
+
+/*
+ * Draws a wire cylinder
+ */
+void renderWireCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
+{
+ int i,j;
+
+ /* Step in z and radius as stacks are drawn. */
+
+ double z = 0.0f;
+ const double zStep = height/stacks;
+
+ /* Pre-computed circle */
+
+ double *sint,*cost;
+ circleTable(&sint,&cost,-slices);
+
+ /* Draw the stacks... */
+
+ for (i=0; i<=stacks; i++)
+ {
+ if (i==stacks)
+ z = height;
+
+ glBegin(GL_LINE_LOOP);
+ for( j=0; j<slices; j++ ) {
+ glNormal3d(cost[j], sint[j], 0.0f);
+ glVertex3d(cost[j]*radius, sint[j]*radius, z );
+ }
+ glEnd();
+
+ z += zStep;
+ }
+
+ /* Draw the slices */
+
+ glBegin(GL_LINES);
+
+ for (j=0; j<slices; j++)
+ {
+ glNormal3d(cost[j], sint[j], 0.0f );
+ glVertex3d(cost[j]*radius, sint[j]*radius, 0.0f );
+ glVertex3d(cost[j]*radius, sint[j]*radius, height);
+ }
+
+ glEnd();
+
+ /* Release sin and cos tables */
+
+ OG_FREE(sint);
+ OG_FREE(cost);
+}
+
+
+#undef num_faces
+
+
+#ifdef _WIN32
+#define NOMINMAX
+#include <windows.h>
+#endif
+
+#include "opengl.h"
+
+GLuint GetBoxDisplayList( const vec3 &sides )
+{
+ GLuint display_list = glGenLists(1);
+ glNewList(display_list,GL_COMPILE);
+ glBegin(GL_QUADS);
+ glNormal3f(0,-1,0);
+ glVertex3f(-sides[0]*0.5f,-sides[1]*0.5f,-sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f,-sides[1]*0.5f,-sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f,-sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f(-sides[0]*0.5f,-sides[1]*0.5f, sides[2]*0.5f);
+
+ glNormal3f(0,1,0);
+ glVertex3f(-sides[0]*0.5f, sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f, sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f, sides[1]*0.5f,-sides[2]*0.5f);
+ glVertex3f(-sides[0]*0.5f, sides[1]*0.5f,-sides[2]*0.5f);
+
+ glNormal3f(1,0,0);
+ glVertex3f( sides[0]*0.5f,-sides[1]*0.5f,-sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f, sides[1]*0.5f,-sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f, sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f,-sides[1]*0.5f, sides[2]*0.5f);
+
+ glNormal3f(-1,0,0);
+ glVertex3f( -sides[0]*0.5f,-sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f( -sides[0]*0.5f, sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f( -sides[0]*0.5f, sides[1]*0.5f,-sides[2]*0.5f);
+ glVertex3f( -sides[0]*0.5f,-sides[1]*0.5f,-sides[2]*0.5f);
+
+ glNormal3f(0,0,-1);
+ glVertex3f(-sides[0]*0.5f,-sides[1]*0.5f, -sides[2]*0.5f);
+ glVertex3f(-sides[0]*0.5f, sides[1]*0.5f, -sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f, sides[1]*0.5f, -sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f,-sides[1]*0.5f, -sides[2]*0.5f);
+
+ glNormal3f(0,0,1);
+ glVertex3f( sides[0]*0.5f,-sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f( sides[0]*0.5f, sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f(-sides[0]*0.5f, sides[1]*0.5f, sides[2]*0.5f);
+ glVertex3f(-sides[0]*0.5f,-sides[1]*0.5f, sides[2]*0.5f);
+ glEnd();
+ glEndList();
+
+ return display_list;
+}
+
+
+
+GLuint GetMultiSphereDisplayList( const vec3 *positions, const float *radii, int num_spheres )
+{
+ CHECK_GL_ERROR();
+ GLuint display_list = glGenLists(1);
+ CHECK_GL_ERROR();
+ glNewList(display_list,GL_COMPILE);
+ CHECK_GL_ERROR();
+
+ for(int i=0; i<num_spheres; i++){
+ glPushMatrix();
+ glTranslatef(positions[i][0], positions[i][1], positions[i][2]);
+ renderSolidSphere(radii[i],12,12);
+ glPopMatrix();
+ }
+ CHECK_GL_ERROR();
+ for(int i=0; i<num_spheres; i++){
+ for(int j=i+1; j<num_spheres; j++){
+ vec3 connection = normalize(positions[j]-positions[i]);
+ vec3 right;// = normalize(vec3(1.0f,1.0f,1.0f));
+ vec3 up;// = normalize(cross(right,connection));
+ //right = normalize(cross(up,connection));
+
+ PlaneSpace(connection, right, up);
+
+ vec3 avg_pos = (positions[j]+positions[i])*0.5f;
+
+ mat4 transform;
+ transform.SetColumn(0,right);
+ transform.SetColumn(1,up);
+ transform.SetColumn(2,connection);
+ transform.SetColumn(3,avg_pos);
+
+ glPushMatrix();
+ glMultMatrixf(transform);
+ renderSolidCylinder(radii[i],
+ distance(positions[i], positions[j]),
+ 12,12);
+ glPopMatrix();
+ }
+ }
+ CHECK_GL_ERROR();
+ glEndList();
+ return display_list;
+}
+
+GLuint GetWireCylinderDisplayList( float radius, float height, GLint slices, GLint stacks )
+{
+ GLuint display_list = glGenLists(1);
+ glNewList(display_list,GL_COMPILE);
+ glPushMatrix();
+ glTranslatef(0.0f,height*0.5f,0.0f);
+ glRotatef(90,1,0,0);
+ renderWireCylinder(radius,height,slices,stacks);
+ glPopMatrix();
+ glEndList();
+ return display_list;
+}
+
+GLuint GetSphereDisplayList( float radius )
+{
+ GLuint display_list = glGenLists(1);
+ glNewList(display_list,GL_COMPILE);
+ glPushMatrix();
+ renderSolidSphere(radius,12,12);
+ glPopMatrix();
+ glEndList();
+ return display_list;
+}