00001
00008 #include <assert.h>
00009 #include <stdio.h>
00010 #include <limits>
00011 #include "Error.h"
00012 #include "Vector3.h"
00013 #include "Cube.h"
00014
00015 struct PlaneVertex
00016 {
00017 float x, y, z;
00018 float s, t, r;
00019 };
00020
00021
00022 const short PLANEVERTEX_TEX_OFFSET = sizeof(float)*3;
00023
00024 const int CUBE_FACE_VERTS_COUNT = 24;
00025 const Vector3f CUBE_FACE_VERTS[] =
00026 {
00027
00028 Vector3f(-1.0f, -1.0f, 1.0f),
00029 Vector3f( 1.0f, -1.0f, 1.0f),
00030 Vector3f( 1.0f, 1.0f, 1.0f),
00031 Vector3f(-1.0f, 1.0f, 1.0f),
00032
00033
00034 Vector3f(-1.0f, 1.0f, -1.0f),
00035 Vector3f( 1.0f, 1.0f, -1.0f),
00036 Vector3f( 1.0f, -1.0f, -1.0f),
00037 Vector3f(-1.0f, -1.0f, -1.0f),
00038
00039
00040 Vector3f( 1.0f, -1.0f, 1.0f),
00041 Vector3f( 1.0f, -1.0f, -1.0f),
00042 Vector3f( 1.0f, 1.0f, -1.0f),
00043 Vector3f( 1.0f, 1.0f, 1.0f),
00044
00045
00046 Vector3f(-1.0f, 1.0f, 1.0f),
00047 Vector3f(-1.0f, 1.0f, -1.0f),
00048 Vector3f(-1.0f, -1.0f, -1.0f),
00049 Vector3f(-1.0f, -1.0f, 1.0f),
00050
00051
00052 Vector3f(-1.0f, 1.0f, 1.0f),
00053 Vector3f( 1.0f, 1.0f, 1.0f),
00054 Vector3f( 1.0f, 1.0f, -1.0f),
00055 Vector3f(-1.0f, 1.0f, -1.0f),
00056
00057
00058 Vector3f(-1.0f, -1.0f, -1.0f),
00059 Vector3f( 1.0f, -1.0f, -1.0f),
00060 Vector3f( 1.0f, -1.0f, 1.0f),
00061 Vector3f(-1.0f, -1.0f, 1.0f)
00062 };
00063
00064
00065 Cube::Cube()
00066 :
00067 mainColor(0.0f, 0.0f, 1.0f, 0.2f),
00068 outlineColor(0.0f, 0.0f, 1.0f, 1.0f),
00069 planeColor(0.5f, 0.5f, 0.5f, 0.5f),
00070 numberOfPlanes(START_PLANE_COUNT),
00071 triangleCount(0),
00072 dir(1.0f, 0.0f, 0.0f),
00073 facesVbo(0),
00074 linesVbo(0),
00075 planeVertsVbo(0),
00076 planeIndicesVbo(0)
00077 {}
00078
00079
00080 Cube::~Cube()
00081 {
00082 if(facesVbo)
00083 glDeleteBuffers(1, &facesVbo);
00084
00085 if(linesVbo)
00086 glDeleteBuffers(1, &linesVbo);
00087
00088 if(planeVertsVbo)
00089 glDeleteBuffers(1, &planeVertsVbo);
00090
00091 if(planeIndicesVbo)
00092 glDeleteBuffers(1, &planeIndicesVbo);
00093 }
00094
00095
00096 void Cube::Init()
00097 {
00098
00099 CubeDef c;
00100 c.c = Point3f(0.0f, 0.0f, 0.0f);
00101 c.dim = 2.0f;
00102
00103 frame = CreateFrame(c);
00104 planes = CreatePlanes(c);
00105
00106
00107 glGenBuffers(1, &facesVbo);
00108 glBindBuffer(GL_ARRAY_BUFFER, facesVbo);
00109 glBufferData(GL_ARRAY_BUFFER, sizeof(CUBE_FACE_VERTS), (void*)CUBE_FACE_VERTS, GL_STATIC_DRAW);
00110
00111 glGenBuffers(1, &linesVbo);
00112 glBindBuffer(GL_ARRAY_BUFFER, linesVbo);
00113 glBufferData(GL_ARRAY_BUFFER, sizeof(CubeFrame), (void*)&frame.line, GL_STATIC_DRAW);
00114
00115
00116 glGenBuffers(1, &planeVertsVbo);
00117 glBindBuffer(GL_ARRAY_BUFFER, planeVertsVbo);
00118 glBufferData(GL_ARRAY_BUFFER, sizeof(PlaneVertex)*MAX_PLANES*6, NULL, GL_DYNAMIC_DRAW);
00119 glBindBuffer(GL_ARRAY_BUFFER, 0);
00120
00121 glGenBuffers(1, &planeIndicesVbo);
00122 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, planeIndicesVbo);
00123 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*MAX_PLANES*12, NULL, GL_DYNAMIC_DRAW);
00124 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00125
00126 UpdatePlanes();
00127 }
00128
00129
00130 void Cube::Draw()
00131 {
00132
00133 glEnableClientState(GL_VERTEX_ARRAY);
00134
00135 glBindBuffer(GL_ARRAY_BUFFER, facesVbo);
00136 glVertexPointer(3, GL_FLOAT, 0, 0);
00137
00138 glColor4f(mainColor.r, mainColor.g, mainColor.b, mainColor.a);
00139 glDrawArrays(GL_QUADS, 0, CUBE_FACE_VERTS_COUNT);
00140 glBindBuffer(GL_ARRAY_BUFFER, 0);
00141
00142 glDisableClientState(GL_VERTEX_ARRAY);
00143 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00144 }
00145
00146
00147 void Cube::DrawOutline()
00148 {
00149
00150 glEnableClientState(GL_VERTEX_ARRAY);
00151
00152 glBindBuffer(GL_ARRAY_BUFFER, linesVbo);
00153 glVertexPointer(3, GL_FLOAT, 0, 0);
00154
00155 glColor4f(outlineColor.r, outlineColor.g, outlineColor.b, outlineColor.a);
00156 glDrawArrays(GL_LINES, 0, (sizeof(CubeFrame) / sizeof(LineSegment)) * 2);
00157
00158 glBindBuffer(GL_ARRAY_BUFFER, 0);
00159
00160 glDisableClientState(GL_VERTEX_ARRAY);
00161 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00162 }
00163
00164
00165 void Cube::DrawPlanes()
00166 {
00167 if(numberOfPlanes > 0)
00168 {
00169 glEnableClientState(GL_VERTEX_ARRAY);
00170 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00171
00172 glBindBuffer(GL_ARRAY_BUFFER, planeVertsVbo);
00173 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, planeIndicesVbo);
00174 glVertexPointer(3, GL_FLOAT, sizeof(PlaneVertex), 0);
00175 glTexCoordPointer(3, GL_FLOAT, sizeof(PlaneVertex), (const void*)PLANEVERTEX_TEX_OFFSET);
00176
00177 glColor4f(planeColor.r, planeColor.g, planeColor.b, planeColor.a);
00178 glDrawElements(GL_TRIANGLES, triangleCount*3, GL_UNSIGNED_SHORT, 0);
00179
00180 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00181 glBindBuffer(GL_ARRAY_BUFFER, 0);
00182
00183 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00184 glDisableClientState(GL_VERTEX_ARRAY);
00185 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00186 }
00187 }
00188
00189
00190 void Cube::SetNumberOfPlanes(int n)
00191 {
00192 if(n < 1)
00193 n = 1;
00194 else if(n > MAX_PLANES)
00195 n = MAX_PLANES;
00196
00197 numberOfPlanes = n;
00198 UpdatePlanes();
00199 }
00200
00201
00202 void Cube::UpdatePlanes()
00203 {
00204 assert(numberOfPlanes > 0 && numberOfPlanes <= MAX_PLANES);
00205
00206
00207 LineSegment line;
00208 line.p1 = Point3f(0.0f, 0.0f, 0.0f);
00209 line.p2 = line.p1 + dir;
00210
00211 float halfLen = 1.0f;
00212 float len = 2.0f;
00213
00214 float min = std::numeric_limits<float>::max();
00215
00216 for(int i = 0; i < 6; i++)
00217 {
00218 float t;
00219 if( Intersect(line, planes.plane[i], t) && t >= 0.0f && t < min)
00220 {
00221 min = t;
00222 }
00223 }
00224
00225 Vector3f d = dir * min;
00226 halfLen = d.Length();
00227 len = halfLen * 2.0f;
00228
00229
00230 PlaneVertex verts[MAX_PLANES*6];
00231 unsigned short indices[MAX_PLANES*12];
00232
00233 Plane p;
00234 p.n = dir;
00235
00236 triangleCount = 0;
00237
00238 int count = 0;
00239 int index = 0;
00240
00241
00242
00243
00244 const float dz = len / (numberOfPlanes + 1);
00245 float z = halfLen - dz;
00246
00247 for(int i = 0; i < numberOfPlanes; i++)
00248 {
00249 p.p = Point3f(0.0f, 0.0f, 0.0f) + z*dir;
00250
00251 Point3f points[6];
00252 int n = Intersect(p, frame, points);
00253 SortPoints(points, n, dir);
00254
00255 for(int j = 0; j < n; j++)
00256 {
00257 int idx = count + j;
00258 verts[idx].x = points[j].x; verts[idx].y = points[j].y; verts[idx].z = points[j].z;
00259
00260 verts[idx].s = (points[j].x + 1.0f) / 2.0f;
00261 verts[idx].t = (points[j].y + 1.0f) / 2.0f;
00262 verts[idx].r = (points[j].z + 1.0f) / 2.0f;
00263 }
00264
00265 int tris = n - 2;
00266 for(int j = 0; j < tris; j++)
00267 {
00268 indices[index++] = (unsigned short)(count );
00269 indices[index++] = (unsigned short)(count + 1 + j);
00270 indices[index++] = (unsigned short)(count + 2 + j);
00271 }
00272
00273 triangleCount += tris;
00274 count += n;
00275
00276 z = z - dz;
00277 }
00278
00279 glBindBuffer(GL_ARRAY_BUFFER, planeVertsVbo);
00280 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(PlaneVertex)*count, (void*)verts);
00281 glBindBuffer(GL_ARRAY_BUFFER, 0);
00282
00283 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, planeIndicesVbo);
00284 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(unsigned short)*index, (void*)indices);
00285 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00286 }