void checkKeyDowns() { if (keyIsDown('d')) { vec3 lp = VectorSub(l,p); vec3 dir = CrossProduct(v, lp); p = VectorSub(p, ScalarMult(Normalize(dir), 0.1)); l = VectorSub(l, ScalarMult(Normalize(dir), 0.1)); } if (keyIsDown('a')) { vec3 lp = VectorSub(l,p); vec3 dir = CrossProduct(lp, v); p = VectorSub(p, ScalarMult(Normalize(dir), 0.1)); l = VectorSub(l, ScalarMult(Normalize(dir), 0.1)); } if (keyIsDown('s')) { vec3 lp = VectorSub(l,p); p = VectorSub(p, ScalarMult(Normalize(lp), 0.1)); l = VectorSub(l, ScalarMult(Normalize(lp), 0.1)); } if (keyIsDown('w')) { vec3 lp = VectorSub(l,p); p = VectorAdd(p, ScalarMult(Normalize(lp), 0.1)); l = VectorAdd(l, ScalarMult(Normalize(lp), 0.1)); } if (keyIsDown('r')) { vec3 lp = VectorSub(l,p); vec3 dir = CrossProduct(v, lp); l = VectorSub(l, ScalarMult(Normalize(dir), 0.5)); } if (keyIsDown('e')) { vec3 lp = VectorSub(l,p); vec3 dir = CrossProduct(v, lp); l = VectorAdd(l, ScalarMult(Normalize(dir), 0.5)); } /* float y1 = ttex.imageData[((int)p.x + (int)p.z * ttex.width) * (ttex.bpp/8)] / 25.0; float y2 = ttex.imageData[(((int)p.x + 1) + ((int)p.z + 1) * ttex.width) * (ttex.bpp/8)] / 25.0; float diff = ((p.x - (int)p.x) + (p.z - (int)p.z))/2; float yDiff = y2-y1; float y = y1 + diff * yDiff + 5; p.y = y; l.y = y; */ //printf("X : %4.2f - Y : %4.2f - Z : %4.2f\n", p.x, p.y, p.z); }
void check_keys(void){ VectorSub(&obj_pos, &cam_pos, &vdiff); if(!fly){ vdiff.y = 0; } if(keyIsDown('w')){ ScalarMult(&vdiff, move_speed, &vdiff); Normalize(&vdiff); VectorAdd(&vdiff, &cam_pos, &cam_pos); if(!fly){ cam_pos.y = calculate_height(cam_pos.x, cam_pos.z, ttex.width, vertexArray) + cam_height; } VectorAdd(&vdiff, &obj_pos, &obj_pos); } else if (keyIsDown('s')) { ScalarMult(&vdiff, move_speed, &vdiff); Normalize(&vdiff); VectorSub(&cam_pos, &vdiff, &cam_pos); if(!fly){ cam_pos.y = calculate_height(cam_pos.x, cam_pos.z, ttex.width, vertexArray) + cam_height; } VectorSub(&obj_pos, &vdiff, &obj_pos); } else if (keyIsDown('a')) { CrossProduct(&up, &vdiff, &vdiff); Normalize(&vdiff); ScalarMult(&vdiff, move_speed, &vdiff); VectorAdd(&vdiff, &cam_pos, &cam_pos); if(!fly){ cam_pos.y = calculate_height(cam_pos.x, cam_pos.z, ttex.width, vertexArray) + cam_height; } VectorAdd(&vdiff, &obj_pos, &obj_pos); } else if (keyIsDown('d')) { CrossProduct(&up, &vdiff, &vdiff); Normalize(&vdiff); ScalarMult(&vdiff, move_speed, &vdiff); VectorSub(&cam_pos, &vdiff, &cam_pos); if(!fly){ cam_pos.y = calculate_height(cam_pos.x, cam_pos.z, ttex.width, vertexArray) + cam_height; } VectorSub(&obj_pos, &vdiff, &obj_pos); } else if (keyIsDown('q')) { exit(0); } else if (keyIsDown('p')) { printf("Your position is; x=%f, y=%f, z=%f\n", cam_pos.x, cam_pos.y, cam_pos.z); printf("Ground height is; y=%f\n", calculate_height(cam_pos.x, cam_pos.z, ttex.width, vertexArray)); } else if (keyIsDown('f')){ fly = !fly; } }
// camera movement. Other keyboard input is handled by keyboardControl void moveTimer(int i) { glutTimerFunc(20, &moveTimer, i); vec3 camRight = Normalize(CrossProduct(camDir, camUp)); vec3 moveDir = {0,0,0}; if (glutKeyIsDown(GLUT_KEY_W)) { moveDir = VectorAdd(moveDir, Normalize(camDir)); } if (glutKeyIsDown(GLUT_KEY_A)) { moveDir = VectorSub(moveDir, camRight); } if (glutKeyIsDown(GLUT_KEY_S)) { moveDir = VectorSub(moveDir, Normalize(camDir)); } if (glutKeyIsDown(GLUT_KEY_D)) { moveDir = VectorAdd(moveDir, camRight); } if (Norm(moveDir) > 0.0) { cam = VectorAdd(cam, ScalarMult(Normalize(moveDir), camMoveSpeed)); } if (!freeCam) cam.y = 1.0 + GetMapHeight(tm, ttex.width, ttex.height, cam.x, cam.z); }
vec3 CalcNormalVector(vec3 a, vec3 b, vec3 c) { vec3 n; n = CrossProduct(VectorSub(a, b), VectorSub(a, c)); n = ScalarMult(n, 1/Norm(n)); return n; }
int sphereInFrustum(vec3 position, float radius) { int i; vec3 closestPoint; for (i=0; i < 5; i++) { closestPoint = VectorAdd(position, ScalarMult(cullingFrustumNormals[i], -radius)); if (DotProduct(closestPoint, cullingFrustumNormals[i]) > 0.f) return 0; } return 1; }
void Ball::handleBallCollision(vector<float> targetPosition , vector<float> targetVelocity , float targetMass , float targetRadius) { //Resolves Ball Collisions //this->setVelocity() vector<float> newPos = addVectors(this->getPosition() , ScalarMult(this->getVelocity() , DELTA_T)); // Position in next iteration vector<float> deltaPos = addVectors(newPos , ScalarMult(targetPosition , -1.0)); //R1 - R2 float speedAlongNormal = dotProduct(deltaPos , addVectors(targetVelocity , ScalarMult(this->getVelocity() , -1.0))); // (V1-V2).N float distSquare = dotProduct(deltaPos , deltaPos); if( (distSquare <= pow( this->getRadius() + targetRadius , 2)) &&( speedAlongNormal >= 0.0) ) { this->setVelocity(solveBallCollision(this->getVelocity(), targetVelocity, newPos, targetPosition, this->getMass(), targetMass , coefficientRestitution).first); /// checks and updates the balls velocity if it collides with some other ball this-> setTimeSinceCollision(BLINK_TIME); //Display changes according to timeSinceCollision } #if defined(DEBUG) || defined(BALL_DEBUG) float x = this->getMass(); float y = this->getMass() * pow(this->getVelocity(),2) * 0.5; string temp_output = "Mass =" + to_string(x) + " Energy= " + to_string(y); cout<<temp_output<<"\n"; #endif }
void check_keys(void){ VectorSub(&obj_pos, &cam_pos, &vdiff); if(keyIsDown('w')){ ScalarMult(&vdiff, move_speed, &vdiff); Normalize(&vdiff); VectorAdd(&vdiff, &cam_pos, &cam_pos); VectorAdd(&vdiff, &obj_pos, &obj_pos); } else if (keyIsDown('s')) { ScalarMult(&vdiff, move_speed, &vdiff); Normalize(&vdiff); VectorSub(&cam_pos, &vdiff, &cam_pos); VectorSub(&obj_pos, &vdiff, &obj_pos); } else if (keyIsDown('a')) { CrossProduct(&up, &vdiff, &vdiff); Normalize(&vdiff); ScalarMult(&vdiff, move_speed, &vdiff); VectorAdd(&vdiff, &cam_pos, &cam_pos); VectorAdd(&vdiff, &obj_pos, &obj_pos); } else if (keyIsDown('d')) { CrossProduct(&up, &vdiff, &vdiff); Normalize(&vdiff); ScalarMult(&vdiff, move_speed, &vdiff); VectorSub(&cam_pos, &vdiff, &cam_pos); VectorSub(&obj_pos, &vdiff, &obj_pos); } else if (keyIsDown('u')) { cam_pos.y += 0.1; obj_pos.y += 0.1; } else if (keyIsDown('j')) { cam_pos.y -= 0.1; obj_pos.y -= 0.1; } else if (keyIsDown('r')) { if(dr < 80){ dr += 0.5; } } else if (keyIsDown('t')) { if(dr > -80){ dr -= 0.5; } } else if (keyIsDown('q')) { exit(0); } }
void keyboard(unsigned char key,int x, int y) { Point3D diff; float scale = 0.4; if(key == 'w') { VectorSub(&look_at, &position, &diff); Normalize(&diff); ScalarMult(&diff, scale, &diff); VectorAdd(&look_at, &diff, &look_at); VectorAdd(&position, &diff, &position); } else if(key == 's') { VectorSub(&position, &look_at, &diff); Normalize(&diff); ScalarMult(&diff, scale, &diff); VectorAdd(&look_at, &diff, &look_at); VectorAdd(&position, &diff, &position); } else if(key == 'd') { Point3D y; y.x = 0; y.z = 0; y.y = 1; VectorSub(&position, &look_at, &diff); CrossProduct(&y, &diff, &diff); Normalize(&diff); ScalarMult(&diff, scale, &diff); VectorAdd(&look_at, &diff, &look_at); VectorAdd(&position, &diff, &position); } else if(key == 'a') { Point3D y; y.x = 0; y.z = 0; y.y = 1; VectorSub(&position, &look_at, &diff); CrossProduct(&diff, &y, &diff); Normalize(&diff); ScalarMult(&diff, scale, &diff); VectorAdd(&look_at, &diff, &look_at); VectorAdd(&position, &diff, &position); } else if(key == 'x') { windspeed -= .05; } else if(key == 'c') { windspeed += .05; } else if(key == 'r') { programs[WINDMILL_PROGRAM] = loadShaders("lab3-3.vert", "lab3-3.frag"); printf("Recompiled shaders\n"); } }
void CalcNormalVector(Point3D *a, Point3D *b, Point3D *c, Point3D *result) { Point3D ab, ac, n; VectorSub(a, b, &ab); VectorSub(a, c, &ac); CrossProduct(&ab, &ac, &n); ScalarMult(&n, 1/Norm(&n), &n); result->x = n.x; result->y = n.y; result->z = n.z; }
// Splits v into vn (parallell to n) and vp (perpendicular). Does not demand n to be normalized. void SplitVector(vec3 v, vec3 n, vec3 *vn, vec3 *vp) { GLfloat nlen; GLfloat nlen2; nlen = DotProduct(v, n); nlen2 = n.x*n.x+n.y*n.y+n.z*n.z; // Squared length if (nlen2 == 0) { *vp = v; *vn = SetVector(0, 0, 0); } else { *vn = ScalarMult(n, nlen/nlen2); *vp = VectorSub(v, *vn); } }
// Delar v i vn (parallell med n) och vp (vinkelrŠt). KrŠver INTE att n Šr normerad! void SplitVector(Point3D *v, Point3D *n, Point3D *vn, Point3D *vp) { GLfloat nlen; GLfloat nlen2; nlen = DotProduct(v, n); nlen2 = n->x*n->x+n->y*n->y+n->z*n->z; // lŠngen av n i kvadrat if (nlen2 == 0) { CopyVector(v, vp); SetVector(0, 0, 0, vn); } else { ScalarMult(n, nlen/nlen2, vn); VectorSub(v, vn, vp); } }
// camera movement. Other keyboard input is handled by keyboardControl void moveTimer(int i) { glutTimerFunc(20, &moveTimer, i); vec3 camRight = Normalize(CrossProduct(camDir, camUp)); vec3 moveDir = {0,0,0}; if (glutKeyIsDown(GLUT_KEY_W)) { moveDir = VectorAdd(moveDir, Normalize(camDir)); } if (glutKeyIsDown(GLUT_KEY_A)) { moveDir = VectorSub(moveDir, camRight); } if (glutKeyIsDown(GLUT_KEY_S)) { moveDir = VectorSub(moveDir, Normalize(camDir)); } if (glutKeyIsDown(GLUT_KEY_D)) { moveDir = VectorAdd(moveDir, camRight); } if (Norm(moveDir) > 0.0) { cam = VectorAdd(cam, ScalarMult(Normalize(moveDir), CAM_MOVE_SPEED)); } }
void calc_bone_transform(joint_s * j, int acc) { joint_s * jc; joint_s * rootj = j; mat4 tmp, tmptrans, invtrans; //tmp = IdentityMatrix(); if(acc) tmp = j->parent->tmp; //tmp = j->parent->Mtot; else //tmp = IdentityMatrix(); tmp = Mult(T(cow.pos.x, cow.pos.y, cow.pos.z), Ry(cow.angle)); GLfloat Ms[8][16]; int i=0,ii=0, k=0; float currpos[8*3] = {0}; float bonepos[8*3] = {0}; while(j->child[0] != NULL) { //calc_bone_transform(j->child[0], 1); for(k=1; k < MAX_CHILDREN; k++) { if(j->child[k] != NULL) calc_bone_transform(j->child[k], 1); } jc = j->child[0]; vec3 tmp_bonepos; tmptrans = j->T; tmp = Mult(tmp, tmptrans); invtrans = InvertMat4(tmptrans); tmp = Mult(tmp, Mult(j->R, invtrans)); j->tmp = tmp; j->isnull = 0; //middle of bone tmp_bonepos = ScalarMult( VectorAdd(j->pos, jc->pos), .5); for(ii=0;ii<16;ii++) Ms[i][ii] = (tmp).m[ii]; currpos[i*3] = 10*j->pos.x; currpos[i*3+1] = 10*j->pos.y; currpos[i*3+2] = 10*j->pos.z; bonepos[i*3] = 10*tmp_bonepos.x; bonepos[i*3+1] = 10*tmp_bonepos.y; bonepos[i*3+2] = 10*tmp_bonepos.z; j = j->child[0]; i++; } if(rootj->posvar != NULL) { //printf(rootj->posvar); //printf("\n"); } //printf("%f %f %f\n", currpos[0], currpos[1], currpos[2]); glUniformMatrix4fv(glGetUniformLocation(g_shader, rootj->Mvar), 8, GL_TRUE, Ms[0]); glUniform3fv(glGetUniformLocation(g_shader, rootj->posvar), 8, currpos); glUniform3fv(glGetUniformLocation(g_shader, rootj->boneposvar), 8, bonepos); }
/////////////////////////////////////////////////////// // D E F O R M C Y L I N D E R // // Desc: deformera cylinder meshen enligt skelettet void DeformCylinder() { //vec3 v[kMaxBones]; //float w[kMaxBones]; int row, corner, bonesnum, bonesnum2; //bonesnum = 0; // för samtliga vertexar for (row = 0; row < kMaxRow; row++) { for (corner = 0; corner < kMaxCorners; corner++) { // ---------========= UPG 4 ===========--------- // TODO: skinna meshen mot alla benen. // // data som du kan använda: // g_bonesRes[].rot //Rotation på benen // g_bones[].pos //Benens position // g_boneWeights //g_boneWeights[kMaxRow][kMaxCorners][kMaxBones] // g_vertsOrg //Originalet // g_vertsRes //Det som ska skickas //g_vertsRes[row][corner] = g_vertsOrg[row][corner]; vec3 sum = SetVector(0.0, 0.0, 0.0); for(bonesnum = 0; bonesnum < kMaxBones; bonesnum++) { //Beräknar T för Org och Res mat4 currOrgT = T(g_bones[bonesnum].pos.x, g_bones[bonesnum].pos.y, g_bones[bonesnum].pos.z); mat4 currResT = T(g_bonesRes[bonesnum].pos.x, g_bonesRes[bonesnum].pos.y, g_bonesRes[bonesnum].pos.z); //Beräknar M för Org och Res, och även inverterad M mat4 currOrgM = Mult(currOrgT, g_bones[bonesnum].rot); mat4 currResM = Mult(currResT, g_bonesRes[bonesnum].rot); mat4 currInvM = InvertMat4(currOrgM); mat4 sumOrgM = currOrgM; mat4 sumResM = currResM; mat4 sumInvM = currInvM; for(bonesnum2 = bonesnum - 1; bonesnum2 >= 0; bonesnum2--) { //Beräknar T för Org och Res för ben innan bonesnum mat4 preOrgT = T(g_bones[bonesnum2].pos.x, g_bones[bonesnum2].pos.y, g_bones[bonesnum2].pos.z); mat4 preResT = T(g_bonesRes[bonesnum2].pos.x, g_bonesRes[bonesnum2].pos.y, g_bonesRes[bonesnum2].pos.z); //Beräknar M för Org och Res, och även inverterad M för ben innan bonesnum mat4 preOrgM = Mult(preOrgT, g_bones[bonesnum2].rot); mat4 preResM = Mult(preResT, g_bonesRes[bonesnum2].rot); mat4 preInvM = InvertMat4(preOrgM); //Summerar sumOrgM = Mult(sumOrgM, preOrgM); sumResM = Mult(sumResM, preResM); sumInvM = Mult(preInvM, sumInvM); } vec3 resV = MultVec3(sumOrgM, g_vertsOrg[row][corner]); mat4 temp1 = Mult(sumResM, sumInvM); vec3 temp2 = MultVec3(temp1, resV); temp2 = ScalarMult(temp2, g_boneWeights[row][corner][bonesnum]); sum = VectorAdd(sum, temp2); } g_vertsRes[row][corner] = sum; } } }
void display(void) { // Clear the screen____________________________________ if((cam.x < goalx + 2 && cam.x > goalx - 2) && (cam.z < goalz + 2 && cam.z > goalz - 2)) { third_person = true; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Variables mat4 total, modelView, camMatrix; GLfloat t =(GLfloat)glutGet(GLUT_ELAPSED_TIME)/1000; //Scale with constant to make animation slower. //Read input_____________________________________________ if (third_person) { goal_found = true; if (glutKeyIsDown('t')) { third_person = false; } vec3 pos = {200, 200, 150};// SetVector(keyx,keyy,keyz); //Mouse control_____________________________________________ //fmin and fmax doesn't really make sense but looks good. GLfloat mousexlocal = 0; GLfloat mouseylocal = 0; if (mousex < 350 || mousex > 250) { mousexlocal = 300-mousex; } else { mousexlocal = 0; } deltaphi = deltaphi + deltaphi*-mousexlocal; deltaphi = fmin(0.0001,deltaphi); deltaphi = fmax(deltaphi,2 * PI - 0.0001); forward = MultVec3(Ry(deltaphi*-mousexlocal), forward); vec3 crossvec = CrossProduct(forward,up); if (mousey < 350 || mousey > 250) { mouseylocal = 300-mousey; } else { mouseylocal = 0; } deltatheta = deltatheta + deltatheta* -mouseylocal; deltatheta = fmin(0.0001,deltatheta); deltatheta = fmax(deltatheta,2*PI - 0.0001); forward = MultVec3( ArbRotate(crossvec,deltatheta*-mouseylocal), forward); //Create camera matrix_____________________________________________ camMatrix = lookAtv(pos,VectorAdd(forward,pos),up); } // FIRST PERSON VIEW -------------------------------------------------------- else { vec3 moveVec; if (glutKeyIsDown('w')) // forwards, obviously { vec3 oldcam = cam; //Save old position to check if its legal. moveVec = ScalarMult(VectorSub(cam, SetVector(lookAtPoint.x, cam.y, lookAtPoint.z)), 0.1); // VectorSub makes a vector in the direction we're looking. cam = VectorSub(cam, moveVec); // The new camera position is the old camera position + the move vector cam.y = getHeight(&ttex,cam.x, cam.z)+2; // Get the correct height from the new position GLfloat maze_height = getHeight(&ttexm, cam.x, cam.z); // Get the height of the maze at the new (possible) camera position GLfloat ground_height = getHeight(&ttex, cam.x, cam.z); // Get the height of the ground at the new (possible) camera position //Check if the new position is legal if ((ground_height - maze_height) < ground_height) // If 0, shouldn't move ever: OK! // When does it start to move?? { printf("woot"); cam = oldcam; } } else if (glutKeyIsDown('t')) { third_person = true; } GLfloat mousexlocal = 0; GLfloat mouseylocal = 0; if (mousex < 350 || mousex > 250) { mousexlocal = 300-mousex; } else { mousexlocal = 0; } deltaphi = deltaphi + deltaphi*-mousexlocal; deltaphi = fmin(0.0001,deltaphi); deltaphi = fmax(deltaphi,2 * PI - 0.0001); forward = MultVec3(Ry(deltaphi*-mousexlocal), forward); vec3 crossvec = CrossProduct(forward,up); if (mousey < 350 || mousey > 250) { mouseylocal = 300-mousey; } else { mouseylocal = 0; } deltatheta = deltatheta + deltatheta* -mouseylocal; deltatheta = fmin(0.0001,deltatheta); deltatheta = fmax(deltatheta,2*PI - 0.0001); forward = MultVec3( ArbRotate(crossvec,deltatheta*-mouseylocal), forward); lookAtPoint = VectorAdd(forward,cam); //Create camera matrix_____________________________________________ camMatrix = lookAtv(cam,lookAtPoint,up); } // --------------------------------------------------------// // SKYBOX // --------------------------------------------------------// glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glUseProgram(programSky); glActiveTexture(GL_TEXTURE2); //glBindTexture(GL_TEXTURE_2D, tex2); trans = T(0.0, 0.0, 0.0); rot = Rx(0); total = Mult(trans, rot); glUniformMatrix4fv(glGetUniformLocation(programSky, "mdlMatrix"), 1, GL_TRUE, total.m); lookSky = camMatrix; lookSky.m[3] = 0; lookSky.m[7] = 0; lookSky.m[11] = 0; glUniformMatrix4fv(glGetUniformLocation(programSky, "lookMatrix"), 1, GL_TRUE, lookSky.m); glUniformMatrix4fv(glGetUniformLocation(programSky, "projectionMatrix"), 1, GL_TRUE, projectionMatrix.m); glUniform1i(glGetUniformLocation(programSky, "texUnit2"), 2); // Texture unit 2 DrawModel(skybox, programSky, "in_Position", NULL, "inTexCoord"); glUseProgram(program); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //------------------------------------------------------// //------------------------------------------------------// modelView = IdentityMatrix(); total = Mult(camMatrix, modelView); glActiveTexture(GL_TEXTURE1); glUseProgram(program); glUniformMatrix4fv(glGetUniformLocation(program, "mdlMatrix"), 1, GL_TRUE, total.m); glBindTexture(GL_TEXTURE_2D, tex2); // Bind Our Texture tex1 DrawModel(tm, program,"inPosition", "inNormal", "inTexCoord"); glUseProgram(program); glUniformMatrix4fv(glGetUniformLocation(program, "mdlMatrix"), 0, GL_TRUE, total.m); glBindTexture(GL_TEXTURE_2D, tex1); // Bind Our Texture tex1 DrawModel(mm, program,"inPosition", "inNormal", "inTexCoord"); GLfloat y = getHeight(&ttexm, 200, 147); mat4 trans = T(goalx, 2, goalz); mat4 scale = S(1, 1, 1); total = Mult(total, trans); total = Mult(total, scale); if (goal_found) { char* string = "GOOD JOB!! You won :D"; sfDrawString(100, 100, string); //while(true){}; } glUniformMatrix4fv(glGetUniformLocation(program, "mdlMatrix"), 1, GL_TRUE, total.m); glBindTexture(GL_TEXTURE_2D, tex3); // Bind Our Texture tex1 DrawModel(goal, program,"inPosition", "inNormal", "inTexCoord"); printError("display 2"); glutSwapBuffers(); printf("x %f\n", cam.x); printf("y %f\n", cam.y); printf("z %f\n", cam.z); /* if ( (cam.x < 95) && (cam.x > 85) && */ /* (cam.z < 85) && (cam.z > 75)) */ }
///The thread void* ballThread(void* args) { BallThreadParameters* arg = (BallThreadParameters*)args ; int ID = arg->ID; float myMass = ball[ID]->getMass(); float myRadius = ball[ID]->getRadius(); #if defined(DEBUG) || defined(THREAD_DEBUG) cout << ID << " created \n"; #endif while(true) { //Thread for exitting from the thread. pthread_mutex_lock(&vecMutexThreadTerminate[ID] ); if(threadTerminate[ID]) { pthread_mutex_unlock(&vecMutexThreadTerminate[ID]); break; } pthread_mutex_unlock(&vecMutexThreadTerminate[ID] ); //Functional Code. pthread_mutex_lock(&vecMutexBallPthreads[ID]); while(numBallUpdates == 0 || !vecShouldBallUpdate[ID] ) pthread_cond_wait(&vecCondBallUpdateBegin[ID] , &vecMutexBallPthreads[ID]); while( (numBallUpdates > 0) && ( vecShouldBallUpdate[ID] ) ) { pthread_mutex_lock(&mutexStateVariableUpdate); numBallUpdates--; vecShouldBallUpdate[ID] = false; pthread_mutex_unlock(&mutexStateVariableUpdate); //Timer-related things have been started. ///Generate N messages, and push them all. for(int i=0; i<NUM_BALLS; i++) { if ( i!= ID) { //Construct a message which contains present thread's data. BallDetailsMessage msg; msg.senderID = ID; msg.senderRadius = myRadius; msg.senderMass = myMass; msg.senderVelocity = ball[ID]->getVelocity(); msg.senderPosition = addVectors(ball[ID]->getPosition() , ScalarMult( ball[ID]->getVelocity(), DELTA_T)); msg.receiverID = i; sendMessage(msg); //Send message to everyone. } //Message sent. } #if defined(DEBUG) || defined(THREAD_DEBUG) cout << "thread: " << ID << " will now begin waiting \n"; #endif //waitForMessages(ID); //Deprecated ///Process messages received. for(int i = 1 ; i< NUM_BALLS; i++) { //Pop n-1 messages. pthread_mutex_lock(&vecMutexMailBox[ID]); ///Wait to receive atleast one message. waitForMessage(ID); //ASSERT : MailBox is not empty. BallDetailsMessage msg = mailBox[ID].front(); mailBox[ID].pop(); ///BallToBall Collisions ball[ID]->handleBallCollision(msg.senderPosition , msg.senderVelocity , msg.senderMass , msg.senderRadius); //Changes the velocity,not the pthread_mutex_unlock(&vecMutexMailBox[ID]); } //Ensure that ball isn't speeding float ratio = (ball[ID]->getSpeed() / MAX_VELOCITY); if ( ratio >= 1.0) { ball[ID]->slowDown(ratio); } //Self explanotry code follows ball[ID]->handleWallCollision(table); ball[ID]->displace(DELTA_T); //Updates have ended pthread_cond_signal(&condBallUpdateComplete); } pthread_mutex_unlock(&vecMutexBallPthreads[ID]); } }
Model* GenerateTerrain(TextureData *tex) { int vertexCount = tex->width * tex->height; int triangleCount = (tex->width-1) * (tex->height-1) * 2; int x, z; //GLfloat *vertexArray = malloc(sizeof(GLfloat) * 3 * vertexCount); vertexArray = malloc(sizeof(GLfloat) * 3 * vertexCount); GLfloat *normalArray = malloc(sizeof(GLfloat) * 3 * vertexCount); for(int i = 0; i < 3*vertexCount;i++){ normalArray[i] = 0; } GLfloat *texCoordArray = malloc(sizeof(GLfloat) * 2 * vertexCount); GLuint *indexArray = malloc(sizeof(GLuint) * triangleCount*3); printf("bpp %d\n", tex->bpp); // Temporary normal vector Point3D normal; for (x = 0; x < tex->width; x++) for (z = 0; z < tex->height; z++) { // Vertex array. You need to scale this properly vertexArray[(x + z * tex->width)*3 + 0] = x / 1.0; vertexArray[(x + z * tex->width)*3 + 1] = tex->imageData[(x + z * tex->width) * (tex->bpp/8)] / 5.0; //vertexArray[(x + z * tex->width)*3 + 1] = 0; vertexArray[(x + z * tex->width)*3 + 2] = z / 1.0; // Normal vectors. You need to calculate these. if(x==0){ // Doing something to get rid of warnings int a = 0; a += 1; } else if(x>1 && x<(tex->width-1) && z > 0 && z < (tex->height-1)){ //printf("In general case: x=%d, z=%d\n", x, z); //Lower triangle make_vertice_normal(vertexArray, x, z, tex->width, false, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); ScalarMult(&normal, 1.0/6, &normal); put_vertex_normal(normalArray, x, z-1, tex->width, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); //Upper triangle make_vertice_normal(vertexArray, x, z, tex->width, true, &normal); ScalarMult(&normal, 1.0/6, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); put_vertex_normal(normalArray, x-1, z+1, tex->width, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); } else if(x==1 && z==0){ //printf("In bottom left corner: x=%d, z=%d\n", x, z); //Upper triangle make_vertice_normal(vertexArray, x, z, tex->width, true, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); put_vertex_normal(normalArray, 0, 0, tex->width, &normal); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, 0, 1, tex->width, &normal); put_vertex_normal(normalArray, 1, 1, tex->width, &normal); } else if(x==tex->width-1 && z == tex->height-1){ //printf("In top right corner: x=%d, z=%d\n", x, z); //Lower triangle make_vertice_normal(vertexArray, x, z, tex->width, false, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); put_vertex_normal(normalArray, x, z, tex->width, &normal); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, x, z-1, tex->width, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); } else if(x==1 && z < tex->height-1){ //printf("In left edge: x=%d, z=%d\n", x, z); // Left edge // Lower triangle make_vertice_normal(vertexArray, x, z, tex->width, false, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, x, z-1, tex->width, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); ScalarMult(&normal, 1.0/2, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); // Upper Triangle make_vertice_normal(vertexArray, x, z, tex->width, true, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); put_vertex_normal(normalArray, x-1, z+1, tex->width, &normal); ScalarMult(&normal, 1.0/2, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); } else if(z==0){ //printf("In bottom edge: x=%d, z=%d\n", x, z); // Bottom edge // Upper Triangle make_vertice_normal(vertexArray, x, z, tex->width, true, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); ScalarMult(&normal, 1.0/2, &normal); put_vertex_normal(normalArray, x-1, z+1, tex->width, &normal); } else if(x==tex->width-1 && z < tex->height-1){ //printf("In right edge: x=%d, z=%d\n", x, z); // Right edge // Lower triangle make_vertice_normal(vertexArray, x, z, tex->width, false, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, x, z-1, tex->width, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); ScalarMult(&normal, 1.0/2, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); // Upper Triangle make_vertice_normal(vertexArray, x, z, tex->width, true, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); ScalarMult(&normal, 1.0/2, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); put_vertex_normal(normalArray, x-1, z+1, tex->width, &normal); } else if(z==tex->height-1){ //printf("In top edge: x=%d, z=%d\n", x, z); // Top edge // Lower triangle make_vertice_normal(vertexArray, x, z, tex->width, false, &normal); //printf("Normal: (%f,%f,%f)\n", normal.x, normal.y, normal.z); ScalarMult(&normal, 1.0/3, &normal); put_vertex_normal(normalArray, x-1, z, tex->width, &normal); put_vertex_normal(normalArray, x, z, tex->width, &normal); ScalarMult(&normal, 1.0/2, &normal); put_vertex_normal(normalArray, x, z-1, tex->width, &normal); } // Texture coordinates. You may want to scale them. texCoordArray[(x + z * tex->width)*2 + 0] = 5*(float)x / tex->width; texCoordArray[(x + z * tex->width)*2 + 1] = 5*(float)z / tex->height; } for (x = 0; x < tex->width-1; x++) for (z = 0; z < tex->height-1; z++) { // Triangle 1 indexArray[(x + z * (tex->width-1))*6 + 0] = x + z * tex->width; indexArray[(x + z * (tex->width-1))*6 + 1] = x + (z+1) * tex->width; indexArray[(x + z * (tex->width-1))*6 + 2] = x+1 + z * tex->width; // Triangle 2 indexArray[(x + z * (tex->width-1))*6 + 3] = x+1 + z * tex->width; indexArray[(x + z * (tex->width-1))*6 + 4] = x + (z+1) * tex->width; indexArray[(x + z * (tex->width-1))*6 + 5] = x+1 + (z+1) * tex->width; } // End of terrain generation // Create Model and upload to GPU: Model* model = LoadDataToModel( vertexArray, normalArray, texCoordArray, NULL, indexArray, vertexCount, triangleCount*3); return model; }
//Keyhandler class to move araound in the world. void Camera::handleKeyPress() { //w,a,s,d to move forward,backwards and sideways if(keyIsDown('w')) { vec3 w = Normalize(VectorSub(lookAtPoint,position)); lookAtPoint = VectorAdd(lookAtPoint,ScalarMult(w,velocity)); position = VectorAdd(position,ScalarMult(w,velocity)); } if(keyIsDown('s')) { vec3 s = Normalize(VectorSub(position,lookAtPoint)); lookAtPoint = VectorAdd(lookAtPoint,ScalarMult(s,velocity)); position = VectorAdd(position,ScalarMult(s,velocity)); } if(keyIsDown('a')) { vec3 w = VectorSub(lookAtPoint,position); vec3 a = Normalize(CrossProduct(upVector,w)); lookAtPoint = VectorAdd(lookAtPoint,ScalarMult(a,velocity)); position = VectorAdd(position,ScalarMult(a,velocity)); } if(keyIsDown('d')) { vec3 w = VectorSub(lookAtPoint,position); vec3 d = Normalize(CrossProduct(w,upVector)); lookAtPoint = VectorAdd(lookAtPoint,ScalarMult(d,velocity)); position = VectorAdd(position,ScalarMult(d,velocity)); } //y,h,g,j to rotate camera up, left, down right if(keyIsDown('y')) { vec3 w = VectorSub(lookAtPoint,position); vec3 a = Normalize(VectorAdd(w,ScalarMult(upVector,1.0/10.0))); lookAtPoint = VectorAdd(position,a); } if(keyIsDown('h')) { vec3 w = VectorSub(lookAtPoint,position); vec3 a = Normalize(VectorAdd(w,ScalarMult(upVector,-1.0/10.0))); lookAtPoint = VectorAdd(position,a); } if(keyIsDown('g')) { vec3 w = VectorSub(lookAtPoint,position); vec3 a = Normalize(CrossProduct(upVector,w)); a = Normalize(VectorAdd(w,ScalarMult(a,1.0/10.0))); lookAtPoint = VectorAdd(position,a); } if(keyIsDown('j')) { vec3 w = VectorSub(lookAtPoint,position); vec3 a = Normalize(CrossProduct(upVector,w)); a = Normalize(VectorAdd(w,ScalarMult(a,-1.0/10.0))); lookAtPoint = VectorAdd(position,a); } //space and c to increase or decrease height if(keyIsDown(' ')) { vec3 w = vec3(0,1,0); lookAtPoint = VectorAdd(lookAtPoint,ScalarMult(w,velocity)); position = VectorAdd(position,ScalarMult(w,velocity)); } if(keyIsDown('c')) { vec3 w = vec3(0,-1,0); lookAtPoint = VectorAdd(lookAtPoint,ScalarMult(w,velocity)); position = VectorAdd(position,ScalarMult(w,velocity)); } //p and o to toggle warp pointer on and off if(keyIsDown('p')) { warpPointer = true; } if(keyIsDown('P')) { warpPointer = false; } //m and n to toggle flight mode on and off if(keyIsDown('m')) { flying = true; } if(keyIsDown('M') && !followFlock) { flying = false; } //+ and - to increase or decrease movement speed if(keyIsDown('+')) { velocity = min(3.0,velocity + 1.0); } if(keyIsDown('-')) { velocity = max(1.0,velocity - 1.0); } //1 and 3 to lock or unlock frustum, for debugging purposes if(keyIsDown('1')) { lockFrustum = true; } if(keyIsDown('!')) { lockFrustum = false; } if(keyIsDown('o') && timer > 20 && flying) { timer = 0; followFlock = true; flockIndex++; // Follow next flock each time 'o' is pressed. } if(keyIsDown('O') && followFlock) { followFlock = false; flockIndex--; // Next time 'o' is pressed, we will follow the previous followed flock. } if(keyIsDown('0') && birdView && followFlock) { birdView = false; } if(keyIsDown('=') && !birdView && followFlock) { birdView = true; } timer++; }