std::vector<LightID> NullPartitioner::lights_within_range(const kmVec3& location) { std::vector<std::pair<LightID, float> > lights_in_range; //Find all the lights within range of the location for(LightID light_id: all_lights_) { Light& light = scene().light(light_id); kmVec3 diff; kmVec3Subtract(&diff, &location, &light.position()); float dist = kmVec3Length(&diff); //if(dist < light.range()) { lights_in_range.push_back(std::make_pair(light_id, dist)); //} } //Sort them by distance std::sort(lights_in_range.begin(), lights_in_range.end(), [](std::pair<LightID, float> lhs, std::pair<LightID, float> rhs) { return lhs.second < rhs.second; }); //Return the LightIDs only std::vector<LightID> result; for(std::pair<LightID, float> p: lights_in_range) { result.push_back(p.first); } return result; }
kmVec3* kmVec3ProjectOnToVec3(const kmVec3* pIn, const kmVec3* other, kmVec3* projection) { kmScalar scale = kmVec3Length(pIn) * kmVec3Dot(pIn, other); kmVec3Normalize(projection, other); kmVec3Scale(projection, projection, scale); return projection; }
kmQuaternion *sls_trackball_calc_quat(kmQuaternion *out, float trackball_radius, float trackball_speed, kmVec2 const *p1, kmVec2 const *p2) { //sls_log_info("p1 %f %f, p2 %f %f", p1->x, p1->y, p2->x, p2->y); kmVec3 axis; kmVec3 _p1, _p2, dir; float phi; float t; float epsilon = 0.001; if (sls_vec2_near(p1, p2, epsilon)) { // zero rotation kmQuaternionIdentity(out); return out; } _p1 = (kmVec3){p1->x, p1->y, sls_tb_project_to_sphere(trackball_radius, p1)}; _p2 = (kmVec3){p2->x, p2->y, sls_tb_project_to_sphere(trackball_radius, p2)}; kmVec3Subtract(&dir, &_p1, &_p2); kmVec3Cross(&axis, &_p2, &_p1); t = kmVec3Length(&dir) / (2.0f * trackball_radius); t = fminf(fmaxf(-1.f, t), 1.f); phi = 2.0f * asinf(t) * trackball_speed; kmQuaternion tmp_a, tmp_b; kmQuaternionRotationAxisAngle(&tmp_a, &axis, phi); tmp_b = *out; return kmQuaternionMultiply(out, &tmp_a, &tmp_b); ; }
kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP) { kmVec3 n; kmScalar l = 0; if (!pP->a && !pP->b && !pP->c) { pOut->a = pP->a; pOut->b = pP->b; pOut->c = pP->c; pOut->d = pP->d; return pOut; } n.x = pP->a; n.y = pP->b; n.z = pP->c; l = 1.0f / kmVec3Length(&n); /*Get 1/length*/ kmVec3Normalize(&n, &n); /*Normalize the vector and assign to pOut*/ pOut->a = n.x; pOut->b = n.y; pOut->c = n.z; pOut->d = pP->d * l; /*Scale the D value and assign to pOut*/ return pOut; }
/** * Returns the vector passed in set to unit length * the result is stored in pOut. */ kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn) { /* kmScalar l = 1.0f / kmVec3Length(pIn); kmVec3 v; v.x = pIn->x * l; v.y = pIn->y * l; v.z = pIn->z * l; pOut->x = v.x; pOut->y = v.y; pOut->z = v.z; return pOut;*/ const float magnitude = kmVec3Length(pIn); static const float epsilon = 0.00001f; if (magnitude > epsilon) { const float scale = 1.0f / magnitude; kmVec3Scale(pOut, pIn, scale); //_vmul(v1, scale); } return pOut; }
void MotionRecognizer::quantize(vector<kmVec3>& norm, vector<unsigned long>& seq) { vector<kmVec3>::iterator iter; kmVec3 v; int i, minIdx; float value, minValue; for (iter = norm.begin(); iter != norm.end(); iter++) { minIdx = 0; minValue = 99999; // Classify vectors into the vectors in codebook by Euclidean distance. // And codebook vectors are codded to integer numbers. for (i = 0; i < CODEBOOK_SIZE; i++) { v.x = ((kmVec3)*iter).x - m_codes[i][0]; v.y = ((kmVec3)*iter).y - m_codes[i][1]; v.z = ((kmVec3)*iter).z - m_codes[i][2]; value = kmVec3Length(&v); if (value < minValue) { minIdx = i; minValue = value; } } seq.push_back((unsigned long)minIdx); } }
kmVec3* kmVec3ProjectOnToVec3(const kmVec3* w, const kmVec3* v, kmVec3* projection) { kmVec3 unitW, unitV; kmVec3Normalize(&unitW, w); kmVec3Normalize(&unitV, v); kmScalar cos0 = kmVec3Dot(&unitW, &unitV); kmVec3Scale(projection, &unitV, kmVec3Length(w) * cos0); return projection; }
void lite3d_bounding_vol_setup(struct lite3d_bounding_vol *vol, const kmVec3 *vmin, const kmVec3 *vmax) { float l, w, h; kmVec3 center; SDL_assert(vmin); SDL_assert(vmax); SDL_assert(vol); l = vmax->x - vmin->x; w = vmax->y - vmin->y; h = vmax->z - vmin->z; vol->box[0] = *vmin; vol->box[1].x = vmin->x; vol->box[1].y = vmin->y; vol->box[1].z = vmin->z + h; vol->box[2].x = vmin->x; vol->box[2].y = vmin->y + w; vol->box[2].z = vmin->z + h; vol->box[3].x = vmin->x; vol->box[3].y = vmin->y + w; vol->box[3].z = vmin->z; vol->box[4].x = vmin->x + l; vol->box[4].y = vmin->y; vol->box[4].z = vmin->z; vol->box[5].x = vmin->x + l; vol->box[5].y = vmin->y; vol->box[5].z = vmin->z + h; vol->box[6].x = vmin->x + l; vol->box[6].y = vmin->y + w; vol->box[6].z = vmin->z; vol->box[7] = *vmax; /* calc center vector */ center.x = l / 2; center.y = w / 2; center.z = h / 2; kmVec3Add(&vol->sphereCenter, vmin, ¢er); vol->radius = kmVec3Length(¢er); }
// Normalizes the vector to unit length, stores the result in pOut and returns the result. kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn) { kmScalar l = 1.0f / kmVec3Length(pIn); kmVec3 v; v.x = pIn->x * l; v.y = pIn->y * l; v.z = pIn->z * l; pOut->x = v.x; pOut->y = v.y; pOut->z = v.z; return pOut; }
void frustum_from_vp( ne_frustum *f, kmMat4 *mat) { float len = 0.f; kmVec3 tmp; f->planes[0].normal.x = mat->mat[3] + mat->mat[0]; f->planes[0].normal.y = mat->mat[7] + mat->mat[4]; f->planes[0].normal.z = mat->mat[11] + mat->mat[8]; f->planes[0].distance = mat->mat[15] + mat->mat[12]; f->planes[1].normal.x = mat->mat[3] - mat->mat[0]; f->planes[1].normal.y = mat->mat[7] - mat->mat[4]; f->planes[1].normal.z = mat->mat[11] - mat->mat[8]; f->planes[1].distance = mat->mat[15] - mat->mat[12]; f->planes[2].normal.x = mat->mat[3] - mat->mat[1]; f->planes[2].normal.y = mat->mat[7] - mat->mat[5]; f->planes[2].normal.z = mat->mat[11] - mat->mat[9]; f->planes[2].distance = mat->mat[15] - mat->mat[13]; f->planes[3].normal.x = mat->mat[3] + mat->mat[1]; f->planes[3].normal.y = mat->mat[7] + mat->mat[5]; f->planes[3].normal.z = mat->mat[11] + mat->mat[9]; f->planes[3].distance = mat->mat[15] + mat->mat[13]; f->planes[4].normal.x = mat->mat[3] + mat->mat[2]; f->planes[4].normal.y = mat->mat[7] + mat->mat[6]; f->planes[4].normal.z = mat->mat[11] + mat->mat[10]; f->planes[4].distance = mat->mat[15] + mat->mat[14]; f->planes[5].normal.x = mat->mat[3] - mat->mat[2]; f->planes[5].normal.y = mat->mat[7] - mat->mat[6]; f->planes[5].normal.z = mat->mat[11] - mat->mat[10]; f->planes[5].distance = mat->mat[15] - mat->mat[14]; for (uint8_t i = 0; i < 6; ++i) { len = kmVec3Length(&f->planes[i].normal); kmVec3Fill(&tmp, len, len, len); kmVec3Div(&f->planes[i].normal, &f->planes[i].normal, &tmp); f->planes[i].distance /= len; } }
/** * Returns the vector passed in set to unit length * the result is stored in pOut. */ kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn) { if (!pIn->x && !pIn->y && !pIn->z) return kmVec3Assign(pOut, pIn); kmScalar l = 1.0f / kmVec3Length(pIn); kmVec3 v; v.x = pIn->x * l; v.y = pIn->y * l; v.z = pIn->z * l; pOut->x = v.x; pOut->y = v.y; pOut->z = v.z; return pOut; }
Line *Line::create(const char *fileName, kmVec3 &a, kmVec3 &b, float thickness, float deg, ccColor3B c, kmVec3 &temp, Lightning *lightning) { Line *line = new Line(); line->initWithFile(fileName); line->setTextureRect(CCRectMake(63, 0, 1, 128));//宽第1的中间像素 line->a = a; line->b = b; line->setAnchorPoint(ccp(0, 0.5)); line->setScaleX(kmVec3Length(&temp)/1.0); line->setScaleY(thickness/128); line->setPosition(ccp(a.x, a.y)); line->setRotation(deg); line->setColor(c); line->autorelease(); return line; }
Frustum::IntersectResult Frustum::intersectSphere(const kmVec3& center, float radius) const { IntersectResult result = IntersectResult::INSIDE; int indexFirst = static_cast<int>(FrustumPlane::FRUSTUM_NEAR); int indexNumber = static_cast<int>(FrustumPlane::FRUSTUM_NUMBER); for(int planeIndex = indexFirst; planeIndex < indexNumber; ++planeIndex) { kmPlane plane = _frustumPlanes[static_cast<FrustumPlane>(planeIndex)]; kmVec3 normal = {plane.a, plane.b, plane.c}; float distance = kmPlaneDotCoord(&plane, ¢er); distance = distance / kmVec3Length(&normal); if(distance < -radius) return IntersectResult::OUTSIDE; if(distance <= radius && distance >= -radius) result = IntersectResult::INTERSECT; } return result; }
kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP) { kmVec3 n; kmScalar l = 0; n.x = pP->a; n.y = pP->b; n.z = pP->c; l = 1.0f / kmVec3Length(&n); //Get 1/length kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut pOut->a = n.x; pOut->b = n.y; pOut->c = n.z; pOut->d = pP->d * l; //Scale the D value and assign to pOut return pOut; }
/* \brief calculate projection matrix */ static void _glhckCameraProjectionMatrix(glhckCamera *object) { kmScalar w, h, distanceFromTarget; kmVec3 toTarget; CALL(2, "%p", object); assert(object); assert(object->view.viewport.w > 0.0f && object->view.viewport.h > 0.0f); switch(object->view.projectionType) { case GLHCK_PROJECTION_ORTHOGRAPHIC: w = object->view.viewport.w > object->view.viewport.h ? 1 : object->view.viewport.w / object->view.viewport.h; h = object->view.viewport.w < object->view.viewport.h ? 1 : object->view.viewport.h / object->view.viewport.w; kmVec3Subtract(&toTarget, &object->object->view.translation, &object->object->view.target); distanceFromTarget = kmVec3Length(&toTarget); w *= (distanceFromTarget+object->view.near)/2; h *= (distanceFromTarget+object->view.near)/2; kmMat4OrthographicProjection(&object->view.projection, -w, w, -h, h, object->view.near, object->view.far); break; case GLHCK_PROJECTION_PERSPECTIVE: default: kmMat4PerspectiveProjection( &object->view.projection, object->view.fov, (float)object->view.viewport.w/(float)object->view.viewport.h, object->view.near, object->view.far); break; } }
int main() { lightDir.x=0.5; lightDir.y=.7; lightDir.z=-0.5; kmVec3Normalize(&lightDir,&lightDir); // creates a window and GLES context // create a window and GLES context if (!glfwInit()) exit(EXIT_FAILURE); window = glfwCreateWindow(width, height, "I N V A D E R S ! ! !", NULL, NULL); if (!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwSetWindowSizeCallback(window,window_size_callback); glfwMakeContextCurrent(window); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); // The obj shapes and their textures are loaded cubeTex = loadPNG("resources/textures/dice.png"); loadObj(&cubeObj, "resources/models/cube.gbo", "resources/shaders/textured.vert", "resources/shaders/textured.frag"); shipTex = loadPNG("resources/textures/shipv2.png"); loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj); alienTex = loadPNG("resources/textures/alien.png"); loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj); shotTex = loadPNG("resources/textures/shot.png"); loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj); expTex = loadPNG("resources/textures/explosion.png"); playerPos.x = 0; playerPos.y = 0; playerPos.z = 0; kmMat4Identity(&view); pEye.x = 0; pEye.y = 2; pEye.z = 4; pCenter.x = 0; pCenter.y = 0; pCenter.z = -5; pUp.x = 0; pUp.y = 1; pUp.z = 0; kmMat4LookAt(&view, &pEye, &pCenter, &pUp); // projection matrix, as distance increases // the way the model is drawn is effected kmMat4Identity(&projection); kmMat4PerspectiveProjection(&projection, 45, (float)width/ height, 0.1, 1000); glViewport(0, 0, width,height); // these two matrices are pre combined for use with each model render kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); // initialises glprint's matrix shader and texture initGlPrint(width,height); font1=createFont("resources/textures/font.png",0,256,16,16,16); font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); // only used by glprintf glEnable(GL_DEPTH_TEST); int num_frames = 0; bool quit = false; resetAliens(); for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { playerShots[n].alive = false; } initPointClouds("resources/shaders/particle.vert", "resources/shaders/particle.frag",(float)width/24.0); for (int n = 0; n < MAX_ALIENS; n++) { aliens[n].explosion=createPointCloud(40); resetExposion(aliens[n].explosion); // sets initials positions } glClearColor(0, .5, 1, 1); while (!quit) { // the main loop clock_gettime(0,&ts); // note the time BEFORE we start to render the current frame glfwPollEvents(); if (glfwGetKey(window,GLFW_KEY_ESCAPE)==GLFW_PRESS || glfwWindowShouldClose(window)) quit = true; float rad; // radians rotation based on frame counter glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); frame++; rad = frame * (0.0175f * 2); //kmMat4Identity(&model); kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z); playerCroll += (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral) / 2); // kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3); // kmMat4RotationYawPitchRoll(&rot,0,3.1416,-playerCroll*3); kmMat4Multiply(&model, &model, &rot); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shipTex); drawObj(&shipObj, &mvp, &mv, lightDir, viewDir); glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16, font2,"frame=%i", frame); kmVec3 tmp; playerFireCount--; if (glfwGetKey(window,GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS && playerFireCount < 0) { struct playerShot_t *freeShot; freeShot = getFreeShot(); if (freeShot != 0) { playerFireCount = 15; freeShot->alive = true; kmVec3Assign(&freeShot->pos, &playerPos); } } for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { if (playerShots[n].alive) { playerShots[n].pos.z -= .08; if (playerShots[n].pos.z < -10) playerShots[n].alive = false; //kmMat4Identity(&model); kmMat4Translation(&model, playerShots[n].pos.x, playerShots[n].pos.y, playerShots[n].pos.z); //kmMat4RotationPitchYawRoll(&model, rad * 4, 0, // -rad * 4); kmMat4RotationYawPitchRoll(&rot,rad*4,0,-rad*4); kmMat4Multiply(&model,&model,&rot); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shotTex); drawObj(&shotObj, &mvp, &mv, lightDir, viewDir); } } playerRoll = 0; if (glfwGetKey(window,GLFW_KEY_LEFT)==GLFW_PRESS && playerPos.x > -10) { playerPos.x -= 0.1; playerRoll = .2; } if (glfwGetKey(window,GLFW_KEY_RIGHT)==GLFW_PRESS && playerPos.x < 10) { playerPos.x += 0.1; playerRoll = -.2; } pEye.x = playerPos.x * 1.25; pCenter.x = playerPos.x; pCenter.y = playerPos.y + 1; pCenter.z = playerPos.z; int deadAliens; deadAliens = 0; for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].alive == true) { //kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); //kmMat4RotationPitchYawRoll(&model, -.4, 0, 0); kmMat4RotationYawPitchRoll(&rot,.2,0,0); kmMat4Multiply(&model,&model,&rot); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, alienTex); drawObj(&alienObj, &mvp, &mv, lightDir, viewDir); kmVec3 d; for (int i = 0; i < MAX_PLAYER_SHOTS; i++) { kmVec3Subtract(&d, &aliens[n].pos, &playerShots[i].pos); if (kmVec3Length(&d) < .7 && playerShots[i].alive) { aliens[n].alive = false; playerShots[i].alive = false; aliens[n].exploding = true; resetExposion(aliens[n].explosion); } } } if (aliens[n].alive != true && aliens[n].exploding != true) { deadAliens++; } } if (deadAliens == MAX_ALIENS) { resetAliens(); } // draw explosions after ALL aliens for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].exploding==true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); glBindTexture(GL_TEXTURE_2D, expTex); drawPointCloud(aliens[n].explosion, &mvp); aliens[n].explosion->tick=aliens[n].explosion->tick+0.05; if (aliens[n].explosion->tick>1.25) { aliens[n].exploding=false; } else { // update the explosion for (int i=0; i<aliens[n].explosion->totalPoints; i++) { float t; t=aliens[n].explosion->tick; if (i>aliens[n].explosion->totalPoints/2) t=t/2.0; aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t; aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t; aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t; } } } } // move camera kmMat4LookAt(&view, &pEye, &pCenter, &pUp); kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); kmVec3Subtract(&viewDir,&pEye,&pCenter); kmVec3Normalize(&viewDir,&viewDir); // dump values glPrintf(100, 280, font1,"eye %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z); glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y, pCenter.z); glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20); glfwSwapBuffers(window); ts.tv_nsec+=20000000; // 1000000000 / 50 = 50hz less time to render the frame //thrd_sleep(&ts,NULL); // tinycthread usleep(20000); // while I work out why tinycthread that was working isnt.... :/ } glfwDestroyWindow(window); glfwTerminate(); return 0; }
int main() { lightDir.x=0.5; lightDir.y=.7; lightDir.z=-0.5; kmVec3Normalize(&lightDir,&lightDir); // creates a window and GLES context if (makeContext() != 0) exit(-1); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); // The obj shapes and their textures are loaded cubeTex = loadPNG("resources/textures/dice.png"); loadObj(&cubeObj, "resources/models/cube.gbo", "resources/shaders/textured.vert", "resources/shaders/textured.frag"); shipTex = loadPNG("resources/textures/shipv2.png"); loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj); alienTex = loadPNG("resources/textures/alien.png"); loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj); shotTex = loadPNG("resources/textures/shot.png"); loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj); expTex = loadPNG("resources/textures/explosion.png"); playerPos.x = 0; playerPos.y = 0; playerPos.z = 0; kmMat4Identity(&view); pEye.x = 0; pEye.y = 2; pEye.z = 4; pCenter.x = 0; pCenter.y = 0; pCenter.z = -5; pUp.x = 0; pUp.y = 1; pUp.z = 0; kmMat4LookAt(&view, &pEye, &pCenter, &pUp); // projection matrix, as distance increases // the way the model is drawn is effected kmMat4Identity(&projection); kmMat4PerspectiveProjection(&projection, 45, (float)getDisplayWidth() / getDisplayHeight(), 0.1, 100); glViewport(0, 0, getDisplayWidth(), getDisplayHeight()); // these two matrices are pre combined for use with each model render kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); // initialises glprint's matrix shader and texture initGlPrint(getDisplayWidth(), getDisplayHeight()); font1=createFont("resources/textures/font.png",0,256,16,16,16); font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); // only used by glprintf glEnable(GL_DEPTH_TEST); struct timeval t, ta, t1, t2; // fps stuff gettimeofday(&t1, NULL); int num_frames = 0; bool quit = false; mouse = getMouse(); keys = getKeys(); resetAliens(); for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { playerShots[n].alive = false; } initPointClouds("resources/shaders/particle.vert", "resources/shaders/particle.frag",(float)getDisplayWidth()/24.0); for (int n = 0; n < MAX_ALIENS; n++) { aliens[n].explosion=createPointCloud(40); resetExposion(aliens[n].explosion); // sets initials positions } while (!quit) { // the main loop doEvents(); // update mouse and key arrays // mask of 4 is right mouse if (keys[KEY_ESC]) quit = true; glClearColor(0, .5, 1, 1); // render between two gettimeofday calls so // we can sleep long enough to roughly sync // to ~60fps but not on the pi! // TODO find something a tad more elegent long i; gettimeofday(&t, NULL); i = t.tv_sec * 1e6 + t.tv_usec; // render(); float rad; // radians rotation based on frame counter glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); frame++; rad = frame * (0.0175f * 2); kmMat4Identity(&model); kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z); playerCroll += (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral) / 2); kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3); // kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shipTex); drawObj(&shipObj, &mvp, &mv, lightDir, viewDir); glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16, font2,"frame=%i fps=%3.2f", frame, lfps); kmVec3 tmp; playerFireCount--; if (keys[KEY_LCTRL] && playerFireCount < 0) { struct playerShot_t *freeShot; freeShot = getFreeShot(); if (freeShot != 0) { playerFireCount = 15; freeShot->alive = true; kmVec3Assign(&freeShot->pos, &playerPos); } } for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { if (playerShots[n].alive) { playerShots[n].pos.z -= .08; if (playerShots[n].pos.z < -10) playerShots[n].alive = false; kmMat4Identity(&model); kmMat4Translation(&model, playerShots[n].pos.x, playerShots[n].pos.y, playerShots[n].pos.z); kmMat4RotationPitchYawRoll(&model, rad * 4, 0, -rad * 4); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shotTex); drawObj(&shotObj, &mvp, &mv, lightDir, viewDir); } } playerRoll = 0; if (keys[KEY_CURSL] && playerPos.x > -10) { playerPos.x -= 0.1; playerRoll = .2; } if (keys[KEY_CURSR] && playerPos.x < 10) { playerPos.x += 0.1; playerRoll = -.2; } pEye.x = playerPos.x * 1.25; pCenter.x = playerPos.x; pCenter.y = playerPos.y + 1; pCenter.z = playerPos.z; int deadAliens; deadAliens = 0; for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].alive == true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4RotationPitchYawRoll(&model, -.4, 0, 0); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, alienTex); drawObj(&alienObj, &mvp, &mv, lightDir, viewDir); kmVec3 d; for (int i = 0; i < MAX_PLAYER_SHOTS; i++) { kmVec3Subtract(&d, &aliens[n].pos, &playerShots[i].pos); if (kmVec3Length(&d) < .7 && playerShots[i].alive) { aliens[n].alive = false; playerShots[i].alive = false; aliens[n].exploding = true; resetExposion(aliens[n].explosion); } } } if (aliens[n].alive != true && aliens[n].exploding != true) { deadAliens++; } } if (deadAliens == MAX_ALIENS) { resetAliens(); } // draw explosions after ALL aliens for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].exploding==true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); glBindTexture(GL_TEXTURE_2D, expTex); drawPointCloud(aliens[n].explosion, &mvp); aliens[n].explosion->tick=aliens[n].explosion->tick+0.05; if (aliens[n].explosion->tick>1.25) { aliens[n].exploding=false; } else { // update the explosion for (int i=0; i<aliens[n].explosion->totalPoints; i++) { float t; t=aliens[n].explosion->tick; if (i>aliens[n].explosion->totalPoints/2) t=t/2.0; aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t; aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t; aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t; } } } } // move camera kmMat4LookAt(&view, &pEye, &pCenter, &pUp); kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); kmVec3Subtract(&viewDir,&pEye,&pCenter); kmVec3Normalize(&viewDir,&viewDir); // dump values glPrintf(100, 280, font1,"eye %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z); glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y, pCenter.z); glPrintf(100, 320, font1,"mouse %i,%i %i ", mouse[0], mouse[1], mouse[2]); glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20); swapBuffers(); gettimeofday(&ta, NULL); long j = (ta.tv_sec * 1e6 + ta.tv_usec); i = j - i; if (i < 0) i = 1000000; // pass through - slower that 60fps if (i < 16000) usleep(16000 - i); // every 10 frames average the time taken and store // fps value for later printing with glprintf if (++num_frames % 10 == 0) { gettimeofday(&t2, NULL); float dtf = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) * 1e-6; lfps = num_frames / dtf; num_frames = 0; t1 = t2; } } closeContext(); return 0; }