// 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); }
bool Detour::ClosestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h) { float v0[3], v1[3], v2[3]; VectorSub(v0, c, a); VectorSub(v1, b, a); VectorSub(v2, p, a); const float dot00 = dtVdot2D(v0, v0); const float dot01 = dtVdot2D(v0, v1); const float dot02 = dtVdot2D(v0, v2); const float dot11 = dtVdot2D(v1, v1); const float dot12 = dtVdot2D(v1, v2); // Compute barycentric coordinates const float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); const float u = (dot11 * dot02 - dot01 * dot12) * invDenom; const float v = (dot00 * dot12 - dot01 * dot02) * invDenom; // The (sloppy) epsilon is needed to allow to get height of points which // are interpolated along the edges of the triangles. static const float EPS = 1e-4f; // If point lies inside the triangle, return interpolated ycoord. if (u >= -EPS && v >= -EPS && (u + v) <= 1 + EPS) { h = a[1] + v0[1] * u + v1[1] * v; return true; } return false; }
void land_dynamicshadow(land_t *land,float *light,thing_t *thing) { int i,j,k,x0,x1,y0,y1; float dir[3],up[3],dx[3],dy[3],blight[3],bpos[3],point[3],min[3],max[3]; VectorSub(thing->center,light,dir); VectorNormalize(dir,dir); VectorSet(0,0,1,up); VectorCrossProduct(up,dir,dx); VectorCrossProduct(dir,dx,dy); VectorNormalize(dx,dx); VectorNormalize(dy,dy); VectorScale(dx,thing->radius,dx); VectorScale(dy,thing->radius,dy); VectorSet(1000000,1000000,1000000,min); VectorSet(-1000000,-1000000,-1000000,max); for(i = 0; i < 4; i++) { if(i == 0 || i == 1) { VectorAdd(light,dx,blight); VectorAdd(thing->center,dx,bpos); } else { VectorSub(light,dx,blight); VectorSub(thing->center,dx,bpos); } if(i == 0 || i == 2) { VectorSub(blight,dy,blight); VectorSub(bpos,dy,bpos); } else { VectorAdd(blight,dy,blight); VectorAdd(bpos,dy,bpos); } land_crossline(land,blight,bpos,point); for(j = 0; j < 2; j++) { if(point[j] < min[j]) min[j] = point[j]; if(point[j] > max[j]) max[j] = point[j]; } } x0 = (int)(min[0] / land->step); y0 = (int)(min[1] / land->step); x1 = (int)(max[0] / land->step) + 1; y1 = (int)(max[1] / land->step) + 1; if(x0 < 0) x0 = 0; if(x0 > land->width - 1) x0 = land->width - 1; if(y0 < 0) y0 = 0; if(y0 > land->height - 1) y0 = land->height - 1; if(x1 < 0) x1 = 0; if(x1 > land->width - 1) x1 = land->width - 1; if(y1 < 0) y1 = 0; if(y1 > land->height - 1) y1 = land->height - 1; glBegin(GL_TRIANGLES); for(j = y0; j < y1; j++) for(i = x0; i < x1; i++) { k = land->width * j + i; glVertex3fv(land->vertex[k].v); glVertex3fv(land->vertex[k + 1].v); glVertex3fv(land->vertex[k + land->width].v); glVertex3fv(land->vertex[k + land->width + 1].v); glVertex3fv(land->vertex[k + land->width].v); glVertex3fv(land->vertex[k + 1].v); } glEnd(); }
float land_height(land_t *land,float *point) { int i,j,k; float x,y,dot0,dot1,p00[3],p10[3],p01[3],v10[3],v01[3],point0[3],point1[3],plane[4]; x = point[0] / land->step; y = point[1] / land->step; i = (int)x; j = (int)y; if(i < 0) i = 0; else if(i > land->width - 2) i = land->width - 2; if(j < 0) j = 0; else if(j > land->height - 2) j = land->height - 2; k = land->width * j + i; if(x + y >= 1 + (int)x + (int)y) { // 1st or 2nd triangle VectorCopy(land->vertex[k + land->width + 1].v,p00); VectorCopy(land->vertex[k + land->width].v,p10); VectorCopy(land->vertex[k + 1].v,p01); } else { VectorCopy(land->vertex[k].v,p00); VectorCopy(land->vertex[k + 1].v,p10); VectorCopy(land->vertex[k + land->width].v,p01); } VectorSub(p10,p00,v10); VectorSub(p01,p00,v01); VectorCrossProduct(v10,v01,plane); plane[3] = -VectorDotProduct(plane,p00); VectorCopy(point,point0); VectorCopy(point,point1); point0[2] = 0; point1[2] = 1; dot0 = -VectorDotProduct(plane,point0); dot1 = -VectorDotProduct(plane,point1); return (point0[2] + (point1[2] - point0[2]) * (plane[3] - dot0) / (dot1 - dot0)); }
land_node_vertex_t *land_create_mesh(land_t *land,land_config_t *config) { unsigned char *heightmap; int i,j,k,l,width,height; land_node_vertex_t *vertex; float p00[3],p10[3],p01[3],v10[3],v01[3],n[3]; heightmap = NULL; if(strstr(config->heightmap,".tga") || strstr(config->heightmap,".TGA")) heightmap = LoadTGA(config->heightmap,&width,&height); else if(strstr(config->heightmap,".jpg") || strstr(config->heightmap,".JPG")) heightmap = LoadJPEG(config->heightmap,&width,&height); if(!heightmap) return NULL; vertex = (land_node_vertex_t*)malloc(sizeof(land_node_vertex_t) * width * height); if(!vertex) return NULL; land->vertex = (land_vertex_t*)malloc(sizeof(land_vertex_t) * width * height); if(!land->vertex) return NULL; for(j = 0, k = 0, l = 0; j < height; j++) // create mesh for(i = 0; i < width; i++, k++, l += 4) { VectorSet((float)i * config->step,(float)j * config->step,(float)heightmap[l] / 255.0 * config->altitude,vertex[k].v); VectorSet(0,0,0,vertex[k].n); vertex[k].t0[0] = vertex[k].t1[0] = (float)i / (float)(width - 1); vertex[k].t0[1] = vertex[k].t1[1] = (float)j / (float)(height - 1); vertex[k].t0[0] *= (float)config->num_base; vertex[k].t0[1] *= (float)config->num_base; vertex[k].t1[0] *= (float)config->num_detail; vertex[k].t1[1] *= (float)config->num_detail; VectorCopy(vertex[k].v,land->vertex[k].v); } for(j = 0, k = 0; j < height - 1; j++, k++) // calculate normals for(i = 0; i < width - 1; i++, k++) { VectorCopy(vertex[k].v,p00); VectorCopy(vertex[k + 1].v,p10); VectorCopy(vertex[k + width].v,p01); VectorSub(p10,p00,v10); VectorSub(p01,p00,v01); VectorCrossProduct(v10,v01,n); VectorNormalize(n,n); VectorAdd(vertex[k].n,n,vertex[k].n); VectorAdd(vertex[k + 1].n,n,vertex[k + 1].n); VectorAdd(vertex[k + width].n,n,vertex[k + width].n); VectorCopy(vertex[k + width + 1].v,p00); VectorCopy(vertex[k + width].v,p10); VectorCopy(vertex[k + 1].v,p01); VectorSub(p10,p00,v10); VectorSub(p01,p00,v01); VectorCrossProduct(v10,v01,n); VectorNormalize(n,n); VectorAdd(vertex[k + width + 1].n,n,vertex[k + width + 1].n); VectorAdd(vertex[k + width].n,n,vertex[k + width].n); VectorAdd(vertex[k + 1].n,n,vertex[k + 1].n); } for(i = 0; i < width * height; i++) // normalize normals VectorNormalize(vertex[i].n,vertex[i].n); land->width = width; land->height = height; land->step = config->step; land->lod = config->lod; free(heightmap); return vertex; }
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; }
void DrawMap(Model* map, Model* compass, mat4 view) { vec3 mapNorm = vec3(0,0,1); vec3 camPos = VectorAdd(player->getPos(),vec3(0,2.0,0)); vec3 mapToCam = VectorSub(player->getPos(),player->getLook()); //Put map in front of the cam vec3 mapPos = VectorSub(camPos,mapToCam); mat4 translate= T(mapPos.x,mapPos.y,mapPos.z); view = Mult(view, translate); //Rotate in around Y-axis vec3 mapToCamXZ = mapToCam; mapToCamXZ.y = 0; mapToCamXZ = Normalize(mapToCamXZ); vec3 upVec = CrossProduct(mapNorm, mapToCamXZ); GLfloat angle = acos(DotProduct(mapNorm, mapToCamXZ)); mat4 billRotMat = ArbRotate(upVec, angle); view = Mult(view,billRotMat); //Rotate in around XZ-axis mapToCam = Normalize(mapToCam); angle = acos(DotProduct(mapToCamXZ,mapToCam)); if (mapToCam.y < 0) billRotMat = ArbRotate(vec3(1,0,0), angle); else billRotMat = ArbRotate(vec3(-1,0,0), angle); view = Mult(view,billRotMat); //Rotate map mat4 viewCompass = view; view = Mult(view,ArbRotate(vec3(0,0,1), mapAngle)); view = Mult(view,T(0,0,-0.1)); glUniformMatrix4fv(glGetUniformLocation(billBoardProgram, "camMatrix"), 1, GL_TRUE, player->getCamMatrix().m); glUniformMatrix4fv(glGetUniformLocation(billBoardProgram, "mdlMatrix"), 1, GL_TRUE, view.m); DrawModel(map, billBoardProgram, "inPosition", NULL, "inTexCoord"); //Kompass viewCompass = Mult(viewCompass,T(-0.35,-0.3,0.1)); GLfloat compassAngle = acos(DotProduct(vec3(0,0,1),mapToCamXZ)); if (mapToCam.x < 0) viewCompass = Mult(viewCompass,ArbRotate(vec3(0,0,1), compassAngle)); else viewCompass = Mult(viewCompass,ArbRotate(vec3(0,0,-1), compassAngle)); glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D, compassTex); glUniform1i(glGetUniformLocation(billBoardProgram, "tex1"), 5); glUniformMatrix4fv(glGetUniformLocation(billBoardProgram, "mdlMatrix"), 1, GL_TRUE, viewCompass.m); DrawModel(compass, billBoardProgram, "inPosition", NULL, "inTexCoord"); }
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; }
float calculate_height(float x, float z, int width, GLfloat *vertexArray) { int quad = (floor(x) + floor(z)*width)*3; // Chooses upper or lower triangle, 1 = upper, 0 = lower int upper = (((x - floor(x))+(z - floor(z))) > 1)? 1 : 0; Point3D corner1, corner2, corner3; if(upper){ // Upper triangle int u = 1; int w = 1; corner1.x = vertexArray[quad + (u + w*width)*3 + 0]; corner1.y = vertexArray[quad + (u + w*width)*3 + 1]; corner1.z = vertexArray[quad + (u + w*width)*3 + 2]; u = 0; corner2.x = vertexArray[quad + (u + w*width)*3 + 0]; corner2.y = vertexArray[quad + (u + w*width)*3 + 1]; corner2.z = vertexArray[quad + (u + w*width)*3 + 2]; u = 1; w = 0; corner3.x = vertexArray[quad + (u + w*width)*3 + 0]; corner3.y = vertexArray[quad + (u + w*width)*3 + 1]; corner3.z = vertexArray[quad + (u + w*width)*3 + 2]; } else { // Lower triangle int u = 0; int w = 0; corner1.x = vertexArray[quad + (u + w*width)*3 + 0]; corner1.y = vertexArray[quad + (u + w*width)*3 + 1]; corner1.z = vertexArray[quad + (u + w*width)*3 + 2]; u = 1; corner2.x = vertexArray[quad + (u + w*width)*3 + 0]; corner2.y = vertexArray[quad + (u + w*width)*3 + 1]; corner2.z = vertexArray[quad + (u + w*width)*3 + 2]; u = 0; w = 1; corner3.x = vertexArray[quad + (u + w*width)*3 + 0]; corner3.y = vertexArray[quad + (u + w*width)*3 + 1]; corner3.z = vertexArray[quad + (u + w*width)*3 + 2]; } Point3D v1, v2, normal; VectorSub(&corner2, &corner1, &v1); VectorSub(&corner3, &corner1, &v2); CrossProduct(&v1,&v2,&normal); // Plane equation = A*x + B*y + C*z + D = 0 float A,B,C,D; A = normal.x; B = normal.y; C = normal.z; D = -A*corner1.x - B*corner1.y - C*corner1.z; // y = - (D + A*x + C*z) / B return -(D + A*x + C*z) / B; }
void Plane::set3Points(vec3 v1, vec3 v2, vec3 v3) { vec3 aux1, aux2; aux1 = VectorSub(v1, v2); aux2 = VectorSub(v3, v2); normal = CrossProduct(aux2, aux1); normal = Normalize(normal); point = vec3(v2); d = DotProduct(normal, point); d = -1; }
static FitVector ComputeCenterTangent(const QList<QPointF> &points, int center) { FitVector V1, V2, tHatCenter; FitVector cpointb(points.at(center - 1)); FitVector cpoint(points.at(center)); FitVector cpointa(points.at(center + 1)); V1 = VectorSub(cpointb, cpoint); V2 = VectorSub(cpoint, cpointa); tHatCenter.m_X = ((V1.m_X + V2.m_X) / 2.0); tHatCenter.m_Y = ((V1.m_Y + V2.m_Y) / 2.0); tHatCenter.normalize(); return tHatCenter; }
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; } }
TraceResult IntersectSphere(SphereProperties &sphere, Ray &ray) { TraceResult traceResult; Vector rayToSphereCenter = VectorSub( sphere.center, ray.origin); float lengthRTSC2 = VectorDot( rayToSphereCenter, rayToSphereCenter ); // lengthRTSC2 = length of the ray from the ray's origin to the sphere's center squared float closestApproach = VectorDot( rayToSphereCenter, ray.direction ); if (closestApproach < 0 ) // behind the ray origin { traceResult.hit = false; return traceResult; } float halfCord2 = (sphere.radius * sphere.radius) - lengthRTSC2 + (closestApproach * closestApproach); if(halfCord2 < 0) // no intersection { traceResult.hit = false; return traceResult; } traceResult.hit = true; traceResult.distance = closestApproach - sqrt(halfCord2); return traceResult; }
void land_render_process(land_node_t *node,camera_t *camera) { int lod; float dist,sub[3]; if(!node->left && !node->right) { if(camera_check_box(camera,node->min,node->max)) { VectorAdd(node->min,node->max,sub); VectorScale(sub,0.5,sub); VectorSub(sub,camera->pos,sub); dist = sqrt(sub[0] * sub[0] + sub[1] * sub[1] + sub[2] * sub[2]); if(dist < node->lod) lod = 0; else lod = 1; land_render_node(node,lod); } return; } if(-VectorDotProduct(camera->pos,node->plane) > node->plane[3]) { land_render_process(node->left,camera); if(camera_check_box(camera,node->right->min,node->right->max)) land_render_process(node->right,camera); } else { land_render_process(node->right,camera); if(camera_check_box(camera,node->left->min,node->left->max)) land_render_process(node->left,camera); } }
float distance( vec3_t origin ) { vec3_t vector; VectorSub( origin, bot.cg->refdef.vieworg, vector ); return ( sqrt( vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2] ) / 48 ); }
/* * Takes care of orbit and rotation */ void UpdatePlanetMovement(GLint t) { GLuint i; mat4 ModelToWorld; for(i = 0; i < numberOfPlanets; i++) { t = glutGet(GLUT_ELAPSED_TIME) - planetsList[i].timeOfCreation; vec3 arbAxis = {0,1,0}; ModelToWorld = ArbRotate(planetsList[i].rotationalAxis, planetsList[i].rotationalSpeed*(GLfloat)t); //IdentityMatrix(); //Rotation around own axis ModelToWorld = Mult(T(planetsList[i].startingPosition.x, planetsList[i].startingPosition.y, planetsList[i].startingPosition.z), ModelToWorld); //Offset if(!(planetsList[i].startingPosition.x == planetsList[0].startingPosition.x && planetsList[i].startingPosition.y == planetsList[0].startingPosition.y && planetsList[i].startingPosition.z == planetsList[0].startingPosition.z )) //Dont try to orbit when already at 0 { if(fabs(planetsList[i].startingPosition.x) - arbAxis.x + fabs(planetsList[i].startingPosition.y) - arbAxis.y + fabs(planetsList[i].startingPosition.z) - arbAxis.z == 0) arbAxis = SetVector(1,0,0); arbAxis = Normalize(CrossProduct(VectorSub(planetsList[i].startingPosition, planetsList[0].startingPosition), arbAxis)); ModelToWorld = Mult(T(planetsList[0].center.x, planetsList[0].center.y, planetsList[0].center.z), ModelToWorld); ModelToWorld = Mult(ArbRotate(arbAxis, planetsList[i].orbitalSpeed*(GLfloat)t), ModelToWorld); //Orbit ModelToWorld = Mult(T(-planetsList[0].center.x, -planetsList[0].center.y, -planetsList[0].center.z), ModelToWorld); } planetsList[i].ModelToWorldMatrix = ModelToWorld; } }
/* Returns true if the player is near a tree */ bool nearTree() { Point3D currentPos = player->getPos(); currentPos.y = 0.0; Point3D treePos = currentPos; for(int i=-2; i < 3; i++){ for(int j=-2; j < 3; j++){ treePos.x = floor(currentPos.x)+i; treePos.z = floor(currentPos.z)+j; if(treePos.x >= 0.0 && treePos.z >= 0.0){ Point3D actualTreePos = vec3(treePos.x,0.0,treePos.z); actualTreePos.x += randXZ->xz[(int)treePos.x][(int) treePos.z].x; actualTreePos.z += randXZ->xz[(int)treePos.x][(int) treePos.z].z; Point3D vecFromTree = VectorSub(currentPos, actualTreePos); GLfloat distFromTree = Norm(vecFromTree); if(distFromTree < hitBoxTree){ return true; } } } } return false; }
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"); } }
mat4 lookAtv(vec3 p, vec3 l, vec3 v) { vec3 n = Normalize(VectorSub(p, l)); vec3 u = Normalize(CrossProduct(v, n)); vec3 v2 = CrossProduct(n, u); mat4 rot = {{ u.x, u.y, u.z, 0, v.x, v.y, v.z, 0, n.x, n.y, n.z, 0, 0, 0, 0, 1 }}; mat4 trans = T(-p.x, -p.y, -p.z); return Mult(rot, trans); }
void punshControl(Model* map, mat4 view) { vec3 mapNorm = vec3(0,0,1); vec3 camPos = VectorAdd(player->getPos(),vec3(0,2.0,0)); vec3 mapToCam = VectorSub(player->getPos(),player->getLook()); //Put text in front of the cam vec3 mapPos = VectorSub(camPos,mapToCam); mat4 translate= T(mapPos.x,mapPos.y,mapPos.z); view = Mult(view, translate); //Rotate in around Y-axis vec3 mapToCamXZ = mapToCam; mapToCamXZ.y = 0; mapToCamXZ = Normalize(mapToCamXZ); vec3 upVec = CrossProduct(mapNorm, mapToCamXZ); GLfloat angle = acos(DotProduct(mapNorm, mapToCamXZ)); mat4 billRotMat = ArbRotate(upVec, angle); view = Mult(view,billRotMat); //Rotate in around XZ-axis mapToCam = Normalize(mapToCam); angle = acos(DotProduct(mapToCamXZ,mapToCam)); if (mapToCam.y < 0) billRotMat = ArbRotate(vec3(1,0,0), angle); else billRotMat = ArbRotate(vec3(-1,0,0), angle); view = Mult(view,billRotMat); mat4 viewCompass = view; view = Mult(view,T(0,0,-0.1)); glUniformMatrix4fv(glGetUniformLocation(billBoardProgram, "camMatrix"), 1, GL_TRUE, player->getCamMatrix().m); glUniformMatrix4fv(glGetUniformLocation(billBoardProgram, "mdlMatrix"), 1, GL_TRUE, view.m); DrawModel(map, billBoardProgram, "inPosition", NULL, "inTexCoord"); }
void DrawBillboard(Model* bm, int inx, int inz, mat4 view) { GLfloat x = (GLfloat) inx; GLfloat z = (GLfloat) inz; if(randXZ->xz[inx][(int)z].x == -9999.0) { GLfloat randX; GLfloat randZ; TreeRandomNumberGen(&randX, &randZ, inx, inz); randXZ->xz[inx][(int)z].x = randX; randXZ->xz[inx][(int)z].z = randZ; } x = x + randXZ->xz[inx][inz].x; z = z + randXZ->xz[inx][inz].z; vec3 billVec = VectorSub(player->getPos(),vec3(x,0,z)); vec3 playerLookAt = VectorSub(player->getPos(),player->getLook()); billVec.y = 0; playerLookAt.y = 0; if(Norm(billVec) < treeRenderingDistance && DotProduct(playerLookAt,billVec) > 0) { billVec = Normalize(billVec); playerLookAt.y = 0.0; mat4 translate= T(x, world->findHeight(x, z), z); view = Mult(view, translate); vec3 billNorm = vec3(0,0,1); vec3 upVec = CrossProduct(billNorm, billVec); GLfloat cosAngle = DotProduct(billNorm, billVec); GLfloat angle = acos(cosAngle); mat4 billRotMat = ArbRotate(upVec, angle); view = Mult(view,billRotMat); glUniformMatrix4fv(glGetUniformLocation(billBoardProgram, "camMatrix"), 1, GL_TRUE, player->getCamMatrix().m); glUniformMatrix4fv(glGetUniformLocation(billBoardProgram, "mdlMatrix"), 1, GL_TRUE, view.m); DrawModel(bm, billBoardProgram, "inPosition", NULL, "inTexCoord"); } }
int findcrosspoint(const float *a,const float *b,float *point) { register int i,j,k; float dot0,dot1,angle,p0[3],p1[3],p2[3]; for(i = 0, j = 0, k = 0; i < num_vertexground; i += 3, j += 4, k += 24) { dot0 = -VectorDotProduct(a,&planeground[j]); dot1 = -VectorDotProduct(b,&planeground[j]); VectorSub(b,a,point); VectorScale(point,(planeground[j + 3] - dot0) / (dot1 - dot0),point); VectorAdd(point,a,point); VectorSub(point,&vertexground[k],p0); VectorSub(point,&vertexground[k + 8],p1); VectorSub(point,&vertexground[k + 16],p2); VectorNormalize(p0,p0); VectorNormalize(p1,p1); VectorNormalize(p2,p2); angle = acos(VectorDotProduct(p0,p1)) + acos(VectorDotProduct(p1,p2)) + acos(VectorDotProduct(p2,p0)); if(angle > 6.28) return 1; } return 0; }
bool objectVisible(const vec3 pos, const GLfloat radius) { vec3 frustumCoords = vec3(xValue - frustumRadius * cos(camPos), 0, zValue - frustumRadius * sin(camPos)); Point3D result = VectorSub(frustumCoords, pos); if (Norm(result) < frustumRadius + radius) { return true; } return false; }
inline float CalculateLightRay(Vector &lightLoc, Vector&intersection, Ray &rayToLight) { Vector lightDir = VectorSub(lightLoc, intersection); float distanceToLight = sqrt( (lightDir.x * lightDir.x) + (lightDir.y * lightDir.y) + (lightDir.z * lightDir.z) );//normal float lightDirMagnitudeReciprocal = 1 / distanceToLight; lightDir.x *= lightDirMagnitudeReciprocal; lightDir.y *= lightDirMagnitudeReciprocal; lightDir.z *= lightDirMagnitudeReciprocal; rayToLight.origin = intersection; rayToLight.direction = lightDir; return distanceToLight; }
// 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)); } }
// Look-at code Matrix lookatMatrix(Vector eye, Vector center, Vector up) { Vector f = VectorSub(center, eye); Vector fn = VectorNorm(f); Vector upn = VectorNorm(up); Vector s = VectorCross(fn, upn); Vector u = VectorCross(s, fn); Matrix lookat = MakeMatrix( s.x, s.y, s.z, 0.0f, u.x, u.y, u.z, 0.0f, -f.x, -f.y, -f.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); return lookat; }
// 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); } }
void OnTimer(int value) { // Move the camera using user input if (keyIsDown('a')) { vec3 dir = VectorSub(targetPos, cameraPos); vec3 right_vec = CrossProduct(dir, upVector); right_vec = Normalize(right_vec); cameraPos = VectorSub(cameraPos, right_vec); targetPos = VectorSub(targetPos, right_vec); } else if (keyIsDown('d')) { vec3 dir = VectorSub(targetPos, cameraPos); vec3 right_vec = CrossProduct(dir, upVector); right_vec = Normalize(right_vec); cameraPos = VectorAdd(cameraPos, right_vec); targetPos = VectorAdd(targetPos, right_vec); } if (keyIsDown('w')) { vec3 dir = VectorSub(targetPos, cameraPos); dir = Normalize(dir); cameraPos = VectorAdd(cameraPos, dir); targetPos = VectorAdd(targetPos, dir); } if (keyIsDown('s')) { vec3 dir = VectorSub(targetPos, cameraPos); dir = Normalize(dir); cameraPos = VectorSub(cameraPos, dir); targetPos = VectorSub(targetPos, dir); } glutPostRedisplay(); glutTimerFunc(20, &OnTimer, value); }