00001 #include <clu.h>
00002
00003 CLcolour* cluSetColour(CLcolour* colour,
00004 GLfloat r,
00005 GLfloat g,
00006 GLfloat b,
00007 GLfloat a)
00008 {
00009 colour->r = r;
00010 colour->g = g;
00011 colour->b = b;
00012 colour->a = a;
00013
00014 return colour;
00015 }
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 CLvertex* cluSetVertex(CLvertex* vertex,
00027 GLfloat x,
00028 GLfloat y,
00029 GLfloat z)
00030 {
00031 vertex->x = x;
00032 vertex->y = y;
00033 vertex->z = z;
00034
00035 return vertex;
00036 }
00037
00038 CLnormal* cluSetNormal(CLnormal* normal,
00039 GLfloat i,
00040 GLfloat j,
00041 GLfloat k)
00042 {
00043 normal->i = i;
00044 normal->j = j;
00045 normal->k = k;
00046
00047 return normal;
00048 }
00049
00050 CLUquaternion* cluSetQuaternion(CLUquaternion* quat,
00051 GLfloat x,
00052 GLfloat y,
00053 GLfloat z,
00054 GLfloat w)
00055 {
00056
00057 quat->x = x;
00058 quat->y = y;
00059 quat->z = z;
00060 quat->w = w;
00061
00062
00063 return quat;
00064 }
00065
00066 CLtexcoord* cluSetTexCoord(CLtexcoord* texcoord,
00067 GLfloat s,
00068 GLfloat t)
00069 {
00070 texcoord->s = s;
00071 texcoord->t = t;
00072
00073 return texcoord;
00074 }
00075
00076 CLedgeflag* cluSetEdgeFlag(CLedgeflag* edgeflag,
00077 GLboolean b)
00078 {
00079 *edgeflag = b;
00080
00081 return edgeflag;
00082 }
00083
00084 CLmatrix* cluSetMatrix(CLmatrix* matrix,
00085 GLfloat m00,
00086 GLfloat m01,
00087 GLfloat m02,
00088 GLfloat m03,
00089 GLfloat m10,
00090 GLfloat m11,
00091 GLfloat m12,
00092 GLfloat m13,
00093 GLfloat m20,
00094 GLfloat m21,
00095 GLfloat m22,
00096 GLfloat m23,
00097 GLfloat m30,
00098 GLfloat m31,
00099 GLfloat m32,
00100 GLfloat m33)
00101 {
00102 matrix->m00 = m00;
00103 matrix->m01 = m01;
00104 matrix->m02 = m02;
00105 matrix->m03 = m03;
00106 matrix->m10 = m10;
00107 matrix->m11 = m11;
00108 matrix->m12 = m12;
00109 matrix->m13 = m13;
00110 matrix->m20 = m20;
00111 matrix->m21 = m21;
00112 matrix->m22 = m22;
00113 matrix->m23 = m23;
00114 matrix->m30 = m30;
00115 matrix->m31 = m31;
00116 matrix->m32 = m32;
00117 matrix->m33 = m33;
00118
00119 return matrix;
00120 }
00121
00122 CLmatrix* cluSetMatrixAxesOrigin(CLmatrix* matrix,
00123 const CLnormal* axis_x,
00124 const CLnormal* axis_y,
00125 const CLnormal* axis_z,
00126 const CLvertex* origin)
00127 {
00128 matrix->m00 = axis_x->i;
00129 matrix->m01 = axis_x->j;
00130 matrix->m02 = axis_x->k;
00131 matrix->m03 = 0.0f;
00132 matrix->m10 = axis_y->i;
00133 matrix->m11 = axis_y->j;
00134 matrix->m12 = axis_y->k;
00135 matrix->m13 = 0.0f;
00136 matrix->m20 = axis_z->i;
00137 matrix->m21 = axis_z->j;
00138 matrix->m22 = axis_z->k;
00139 matrix->m23 = 0.0f;
00140 matrix->m30 = origin->x;
00141 matrix->m31 = origin->y;
00142 matrix->m32 = origin->z;
00143 matrix->m33 = 1.0f;
00144
00145 return matrix;
00146 }
00147
00148
00149
00150 CLvertex* cluSetVertexMatrixOrigin(CLvertex* vertex, const CLmatrix* matrix)
00151 {
00152 vertex->x = matrix->m30;
00153 vertex->y = matrix->m31;
00154 vertex->z = matrix->m32;
00155
00156 return vertex;
00157 }
00158
00159 CLvertex* cluSetVertexRayDistance(CLvertex* vf,
00160 const CLUray* ray, float t)
00161 {
00162 CLnormal offset;
00163
00164 clCopyNormal(&offset, &ray->direction);
00165 cluNormalScale(&offset, t);
00166 clCopyVertex(vf, &ray->origin);
00167 cluVertexAdd(vf, &offset);
00168
00169 return vf;
00170 }
00171
00172
00173 CLnormal* cluSetNormalMatrixAxisX(CLnormal* normal, const CLmatrix* matrix)
00174 {
00175 normal->i = matrix->m00;
00176 normal->j = matrix->m01;
00177 normal->k = matrix->m02;
00178
00179 return normal;
00180 }
00181
00182
00183 CLnormal* cluSetNormalMatrixAxisY(CLnormal* normal, const CLmatrix* matrix)
00184 {
00185 normal->i = matrix->m10;
00186 normal->j = matrix->m11;
00187 normal->k = matrix->m12;
00188
00189 return normal;
00190 }
00191
00192
00193 CLnormal* cluSetNormalMatrixAxisZ(CLnormal* normal, const CLmatrix* matrix)
00194 {
00195 normal->i = matrix->m20;
00196 normal->j = matrix->m21;
00197 normal->k = matrix->m22;
00198
00199 return normal;
00200 }
00201
00202 CLnormal* cluSetNormalPlane(CLnormal* normal, const CLUplane* plane)
00203 {
00204 normal->i = plane->a;
00205 normal->j = plane->b;
00206 normal->k = plane->c;
00207
00208 return normal;
00209 }
00210
00211 CLnormal* cluSetNormalTriangle(CLnormal* normal,
00212 const CLvertex* v0,
00213 const CLvertex* v1,
00214 const CLvertex* v2)
00215 {
00216 CLnormal n0;
00217 CLnormal n1;
00218
00219 cluNormalDifference(&n0, v0, v1);
00220 cluNormalDifference(&n1, v0, v2);
00221
00222 if ((cluNormalMagnitude(&n0) != 0.0f) && (cluNormalMagnitude(&n1) != 0.0f))
00223 {
00224
00225
00226
00227
00228
00229 cluNormalCrossProduct(normal, &n0, &n1);
00230
00231
00232
00233 }
00234
00235 return normal;
00236 }
00237
00238 CLnormal* cluSetNormalQuaternionAxis(CLnormal* normal,
00239 const CLUquaternion* quaternion)
00240 {
00241 GLfloat s;
00242
00243 s = sqrt(1.0f - quaternion->w * quaternion->w);
00244
00245 if (s == 0.0f)
00246 s = 1;
00247
00248 normal->i = quaternion->x / s;
00249 normal->j = quaternion->y / s;
00250 normal->k = quaternion->z / s;
00251
00252 return normal;
00253 }
00254
00255 CLmatrix* cluSetMatrixOrientation(CLmatrix* matrix,
00256 const CLUquaternion* orientation)
00257 {
00258 GLfloat xx;
00259 GLfloat xy;
00260 GLfloat xz;
00261 GLfloat xw;
00262
00263 GLfloat yy;
00264 GLfloat yz;
00265 GLfloat yw;
00266
00267 GLfloat zz;
00268 GLfloat zw;
00269
00270 CLnormal temp;
00271
00272 xx = orientation->x * orientation->x;
00273 xy = orientation->x * orientation->y;
00274 xz = orientation->x * orientation->z;
00275 xw = orientation->x * orientation->w;
00276
00277 yy = orientation->y * orientation->y;
00278 yz = orientation->y * orientation->z;
00279 yw = orientation->y * orientation->w;
00280
00281 zz = orientation->z * orientation->z;
00282 zw = orientation->z * orientation->w;
00283
00284 temp.i = 1 - 2 * (yy + zz);
00285 temp.j = 2 * (xy - zw);
00286 temp.k = 2 * (xz + yw);
00287
00288 cluNormalNormalise(&temp);
00289
00290 matrix->m00 = temp.i;
00291 matrix->m01 = temp.j;
00292 matrix->m02 = temp.k;
00293
00294 temp.i = 2 * (xy + zw);
00295 temp.j = 1 - 2 * (xx + zz);
00296 temp.k = 2 * (yz - xw);
00297
00298 cluNormalNormalise(&temp);
00299
00300 matrix->m10 = temp.i;
00301 matrix->m11 = temp.j;
00302 matrix->m12 = temp.k;
00303
00304 temp.i = 2 * (xz - yw);
00305 temp.j = 2 * (yz + xw);
00306 temp.k = 1 - 2 * (xx + yy);
00307
00308 cluNormalNormalise(&temp);
00309
00310 matrix->m20 = temp.i;
00311 matrix->m21 = temp.j;
00312 matrix->m22 = temp.k;
00313
00314 return matrix;
00315 }
00316
00317 CLmatrix* cluSetMatrixPosition(CLmatrix* matrix, const CLvertex* position)
00318 {
00319 matrix->m30 = position->x;
00320 matrix->m31 = position->y;
00321 matrix->m32 = position->z;
00322
00323 return matrix;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 CLimage* cluSetImageChessBoard(CLimage* image)
00341 {
00342 GLuint i;
00343 GLboolean flag;
00344 GLubyte data[256];
00345
00346 if (!image)
00347 return 0;
00348
00349 flag = GL_FALSE;
00350
00351 clClearImage(image);
00352
00353 image->width = 8;
00354 image->height = 8;
00355 image->format = GL_RGBA;
00356 image->type = GL_UNSIGNED_BYTE;
00357
00358
00359 for (i = 0; i < 64; i++)
00360 {
00361 if (!(i % 8))
00362 flag = !flag;
00363
00364 if (flag)
00365 {
00366 data[4 * i ] = 0;
00367 data[4 * i+ 1] = 0;
00368 data[4 * i + 2] = 0;
00369 data[4 * i + 3] = 255;
00370 }
00371 else
00372 {
00373 data[4 * i ] = 255;
00374 data[4 * i+ 1] = 255;
00375 data[4 * i + 2] = 255;
00376 data[4 * i + 3] = 255;
00377 }
00378
00379 flag = !flag;
00380 }
00381
00382
00383 image->data = (GLvoid*)malloc(256 * sizeof(GLubyte));
00384 image->data = (GLvoid*)memcpy(image->data, data, 256 * sizeof(GLubyte));
00385
00386 return image;
00387 }
00388
00389 CLimage* cluSetImageColorBuffer(CLimage* image)
00390 {
00391 GLfloat viewport[4];
00392
00393 clClearImage(image);
00394
00395 glGetFloatv(GL_VIEWPORT, viewport);
00396
00397 image->width = viewport[2];
00398 image->height = viewport[3];
00399 image->format = GL_RGBA;
00400 image->type = GL_UNSIGNED_BYTE;
00401
00402 image->data = (GLubyte*)malloc(image->width * image->height
00403 * 4 * sizeof(GLubyte));
00404
00405 glReadPixels(viewport[0], viewport[1],
00406 image->width, image->height,
00407 image->format, image->type, image->data);
00408
00409 return image;
00410 }
00411
00412 CLlight* cluSetLightSubtle(CLlight* light)
00413 {
00414 clDefaultLight(light);
00415
00416 light->specular.r = 0.1f;
00417 light->specular.g = 0.1f;
00418 light->specular.b = 0.1f;
00419
00420 return light;
00421 }
00422
00423 CLlight* cluSetLightPoint(CLlight* light, const CLvertex* pos)
00424 {
00425 clDefaultLight(light);
00426
00427 light->position[0] = pos->x;
00428 light->position[1] = pos->y;
00429 light->position[2] = pos->z;
00430 light->position[3] = 1.0f;
00431
00432 return light;
00433 }
00434
00435 CLlight* cluSetLightDirectional(CLlight* light, const CLnormal* dir)
00436 {
00437 clDefaultLight(light);
00438
00439 light->position[0] = dir->i;
00440 light->position[1] = dir->j;
00441 light->position[2] = dir->k;
00442 light->position[3] = 0.0f;
00443
00444 return light;
00445 }
00446
00447 CLlight* cluSetLightSpotLight(CLlight* light,
00448 const CLvertex* pos,
00449 const CLnormal* dir,
00450 GLfloat cutoff)
00451 {
00452 clDefaultLight(light);
00453
00454 light->position[0] = pos->x;
00455 light->position[1] = pos->y;
00456 light->position[2] = pos->z;
00457 light->position[3] = 1.0f;
00458
00459 clCopyNormal(&light->spot_direction, dir);
00460
00461 light->spot_cutoff = cutoff;
00462
00463 return light;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 CLtexture* cluSetTextureImage(CLtexture* texture, const CLimage* image)
00475 {
00476 GLint max_size = 0;
00477
00478 clClearImage(&texture->image);
00479
00480
00481 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
00482
00483 if (image->width <= max_size)
00484 texture->image.width = 1 << (int)floor((log((double)image->width)/log(2.0f)) + 0.5f);
00485 else
00486 texture->image.width = max_size;
00487
00488 if (image->height <= max_size)
00489 texture->image.height = 1 << (int)floor((log((double)image->height)/log(2.0f)) + 0.5f);
00490 else
00491 texture->image.height = max_size;
00492
00493 texture->image.format = image->format;
00494 texture->image.type = image->type;
00495
00496 texture->image.data = (GLvoid*)malloc(clImageDataSize(&texture->image));
00497
00498 gluScaleImage(image->format,
00499 image->width,
00500 image->height,
00501 image->type,
00502 image->data,
00503 texture->image.width,
00504 texture->image.height,
00505 texture->image.type,
00506 texture->image.data);
00507
00508
00509
00510 return texture;
00511 }
00512
00513 CLUquaternion* cluSetQuaternionAxisAngle(CLUquaternion* quaternion,
00514 const CLnormal* axis,
00515 GLfloat angle)
00516 {
00517 GLfloat s;
00518 GLfloat c;
00519 CLnormal temp;
00520
00521 s = sin(CL_DEG2RAD(angle / 2.0f));
00522 c = cos(CL_DEG2RAD(angle / 2.0f));
00523
00524 clCopyNormal(&temp, axis);
00525
00526
00527 quaternion->x = temp.i * s;
00528 quaternion->y = temp.j * s;
00529 quaternion->z = temp.k * s;
00530 quaternion->w = c;
00531
00532 cluQuaternionNormalise(quaternion);
00533 return quaternion;
00534 }
00535
00536
00537 CLUquaternion* cluSetQuaternionMatrix(CLUquaternion* quaternion,
00538 const CLmatrix* matrix) {
00539 GLfloat T = matrix->m00 + matrix->m11 + matrix->m22 + 1.0;
00540 GLfloat S;
00541
00542 if(T>0.00000001) {
00543 S = sqrt(T) * 2;
00544
00545 quaternion->x = ( matrix->m12 - matrix->m21 ) / S;
00546 quaternion->y = ( matrix->m20 - matrix->m02 ) / S;
00547 quaternion->z = ( matrix->m01 - matrix->m10 ) / S;
00548 quaternion->w = 0.25 * S;
00549 }
00550 else {
00551 if(matrix->m00 > matrix->m11 && matrix->m00 > matrix->m22) {
00552 S = sqrt( 1.0 + matrix->m00 - matrix->m11 - matrix->m22) * 2;
00553
00554 quaternion->x = 0.25 * S;
00555 quaternion->y = (matrix->m10 + matrix->m01 ) / S;
00556 quaternion->z = (matrix->m20 + matrix->m02 ) / S;
00557 quaternion->w = (matrix->m21 - matrix->m12 ) / S;
00558 }
00559 else if(matrix->m11 > matrix->m22) {
00560 S = sqrt( 1.0 + matrix->m11 - matrix->m00 - matrix->m22) * 2;
00561
00562 quaternion->x = (matrix->m10 + matrix->m01 ) / S;
00563 quaternion->y = 0.25 * S;
00564 quaternion->z = (matrix->m21 + matrix->m12 ) / S;
00565 quaternion->w = (matrix->m20 - matrix->m02 ) / S;
00566 }
00567 else {
00568 S = sqrt( 1.0 + matrix->m22 - matrix->m00 - matrix->m11) * 2;
00569
00570 quaternion->x = (matrix->m20 + matrix->m02 ) / S;
00571 quaternion->y = (matrix->m21 + matrix->m12 ) / S;
00572 quaternion->z = 0.25 * S;
00573 quaternion->w = (matrix->m10 - matrix->m01 ) / S;
00574 }
00575 }
00576
00577 return quaternion;
00578 }
00579
00580 CLUplane* cluSetPlaneVertexNormal(CLUplane* plane,
00581 const CLvertex* vertex,
00582 const CLnormal* normal)
00583 {
00584 plane->a = normal->i;
00585 plane->b = normal->j;
00586 plane->c = normal->k;
00587
00588 plane->d = -plane->a * vertex->x - plane->b * vertex->y - plane->c * vertex->z;
00589
00590
00591
00592
00593
00594 return plane;
00595 }
00596
00597 CLUplane* cluSetPlaneTriangle(CLUplane* plane,
00598 const CLvertex* vertex0,
00599 const CLvertex* vertex1,
00600 const CLvertex* vertex2)
00601 {
00602 CLnormal normal;
00603
00604 cluSetNormalTriangle(&normal, vertex0, vertex1, vertex2);
00605 cluSetPlaneVertexNormal(plane, vertex0, &normal);
00606
00607 return plane;
00608 }
00609
00610 CLUfrustum* cluSetFrustumModelviewProjection(CLUfrustum* frustum,
00611 const CLmatrix* modelview,
00612 const CLmatrix* projection)
00613 {
00614 CLmatrix clip;
00615
00616 clCopyMatrix(&clip, modelview);
00617 cluMatrixTransform(&clip, projection);
00618
00619 frustum->left.a = clip.m03 + clip.m00;
00620 frustum->left.b = clip.m13 + clip.m10;
00621 frustum->left.c = clip.m23 + clip.m20;
00622 frustum->left.d = clip.m33 + clip.m30;
00623
00624 cluPlaneNormalise(&frustum->left);
00625
00626 frustum->right.a = clip.m03 - clip.m00;
00627 frustum->right.b = clip.m13 - clip.m10;
00628 frustum->right.c = clip.m23 - clip.m20;
00629 frustum->right.d = clip.m33 - clip.m30;
00630
00631 cluPlaneNormalise(&frustum->right);
00632
00633 frustum->bottom.a = clip.m03 + clip.m01;
00634 frustum->bottom.b = clip.m13 + clip.m11;
00635 frustum->bottom.c = clip.m23 + clip.m21;
00636 frustum->bottom.d = clip.m33 + clip.m31;
00637
00638 cluPlaneNormalise(&frustum->bottom);
00639
00640 frustum->top.a = clip.m03 - clip.m01;
00641 frustum->top.b = clip.m13 - clip.m11;
00642 frustum->top.c = clip.m23 - clip.m21;
00643 frustum->top.d = clip.m33 - clip.m31;
00644
00645 cluPlaneNormalise(&frustum->top);
00646
00647 frustum->near.a = clip.m03 - clip.m02;
00648 frustum->near.b = clip.m13 - clip.m12;
00649 frustum->near.c = clip.m23 - clip.m22;
00650 frustum->near.d = clip.m33 - clip.m32;
00651
00652 cluPlaneNormalise(&frustum->near);
00653
00654 frustum->far.a = clip.m03 + clip.m02;
00655 frustum->far.b = clip.m13 + clip.m12;
00656 frustum->far.c = clip.m23 + clip.m22;
00657 frustum->far.d = clip.m33 + clip.m32;
00658
00659 cluPlaneNormalise(&frustum->far);
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 return frustum;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 CLUsphere* cluSetSphereMesh(CLUsphere* sphere,
00698 const CLmesh* mesh)
00699 {
00700 GLuint i;
00701 GLfloat d;
00702
00703 cluMeshLocalOrigin(&sphere->origin, mesh);
00704
00705 sphere->radius = 0.0f;
00706
00707 for (i = 0; i < mesh->num_vertices; i++)
00708 {
00709 d = cluVertexDistance(mesh->vertices + i, &sphere->origin);
00710
00711 if (sphere->radius < d)
00712 sphere->radius = d;
00713 }
00714
00715 return sphere;
00716 }
00717
00718 CLUsphere* cluSetSphereModel(CLUsphere* sphere,
00719 const CLmodel* model)
00720 {
00721 GLuint i;
00722 GLuint j;
00723 GLfloat d;
00724 CLmesh* mesh;
00725
00726 cluModelLocalOrigin(&sphere->origin, model);
00727
00728 sphere->radius = 0.0f;
00729
00730 for (i = 0; i < model->num_meshes; i++)
00731 {
00732 mesh = model->meshes[i];
00733
00734 for (j = 0; j < mesh->num_vertices; j++)
00735 {
00736 d = cluVertexDistance(mesh->vertices + j, &sphere->origin);
00737
00738 if (sphere->radius < d)
00739 sphere->radius = d;
00740 }
00741 }
00742
00743 return sphere;
00744 }
00767 CLUcone* cluSetConeSphereVertex(CLUcone* cone,
00768 const CLUsphere* sphere,
00769 const CLvertex* vertex)
00770 {
00771 float d;
00772 float pt;
00773
00774 d = cluVertexDistance(&sphere->origin, vertex);
00775 pt = sqrt((d + sphere->radius) * (d - sphere->radius));
00776
00777 cone->half_angle = CL_RAD2DEG(atan2(sphere->radius, pt));
00778
00779 clCopyVertex(&cone->origin, vertex);
00780 cluNormalNormalise(cluNormalDifference(&cone->direction,
00781 &sphere->origin, &cone->origin));
00782
00783 return cone;
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 }
00800
00801 CLUray* cluSetRay(CLUray* ray,
00802 GLfloat x, GLfloat y, GLfloat z,
00803 GLfloat i, GLfloat j, GLfloat k)
00804 {
00805 cluSetVertex(&ray->origin, x, y, z);
00806 cluSetNormal(&ray->direction, i, j, k);
00807 cluNormalNormalise(&ray->direction);
00808
00809 return ray;
00810 }
00811
00812 CLUalignedbox* cluSetAlignedBox(CLUalignedbox* box,
00813 CLvertex* min,
00814 CLvertex* max)
00815 {
00816 clCopyVertex(&box->min, min);
00817 clCopyVertex(&box->max, max);
00818
00819 return box;
00820 }