static VECT * calc_face_normals(VECT *p_vertexes, int vertexnum, tface *p_face, int facenum) { VECT *p_face_normals = (VECT *)mmalloc(sizeof(p_face_normals[0])*(facenum/3)); int i,face; for(i = 0, face = 0; i < facenum; i+=3, face++) { face_normal(p_vertexes+p_face[i], p_vertexes+p_face[i+1], p_vertexes+p_face[i+2], p_face_normals+face); } return(p_face_normals); }
void CubeBlock::InitStatic(GLRenderingContext *rc) { Quaternion qs[6] = { Quaternion(Vector3f(0,1,0), -90), Quaternion(Vector3f(0,1,0), 180), Quaternion(Vector3f(0,1,0), 90), Quaternion::Identity(), Quaternion(Vector3f(1,0,0), -90), Quaternion(Vector3f(1,0,0), 90), }; for (int i = 0; i < 6; i++) qs[i].ToMatrix(face_transform[i]); face = new Mesh(rc); border = new Mesh(rc); border_reduced = new Mesh(rc); face_pickMode = new Mesh(rc); face->LoadRaw("face.raw"); border->LoadRaw("border.raw"); border_reduced->LoadRaw("border_reduced.raw"); face_pickMode->LoadRaw("face_pick.raw"); if (!GLEW_ARB_shader_objects) return; Texture2D face_mask("face_mask.tga", GL_TEXTURE0); Texture2D face_normal("face_normal.tga", GL_TEXTURE1); Texture2D border_normal("border_normal.tga", GL_TEXTURE1); Texture2D border_reduced_normal("border_reduced_normal.tga", GL_TEXTURE1); Texture2D border_specular("border_specular.tga", GL_TEXTURE2); face_mask.SetFilters(GL_LINEAR, GL_LINEAR); face_normal.SetFilters(GL_LINEAR, GL_LINEAR); border_normal.SetFilters(GL_LINEAR, GL_LINEAR); border_reduced_normal.SetFilters(GL_LINEAR, GL_LINEAR); border_specular.SetFilters(GL_LINEAR, GL_LINEAR); face->BindTexture(face_mask); face->BindNormalMap(face_normal); border->BindNormalMap(border_normal); border->BindSpecularMap(border_specular); border_reduced->BindNormalMap(border_reduced_normal); DrawWhiteBorders(rc, false); }
// Returns final color uint8_t raytrace(vec3 pos, vec3 dir, hit* info) { // Finish early if there's no direction if (dir.x == 0.0f && dir.y == 0.0f && dir.z == 0.0f) { goto nohit; } vec3 start = pos; int x = (int) pos.x; int y = (int) pos.y; int z = (int) pos.z; int x_dir = dir.x >= 0.0f ? 1 : -1; int y_dir = dir.y >= 0.0f ? 1 : -1; int z_dir = dir.z >= 0.0f ? 1 : -1; float dx_off = x_dir > 0 ? 1.0f : 0.0f; float dy_off = y_dir > 0 ? 1.0f : 0.0f; float dz_off = z_dir > 0 ? 1.0f : 0.0f; int x_face = x_dir > 0 ? FACE_LEFT : FACE_RIGHT; int y_face = y_dir > 0 ? FACE_BOTTOM : FACE_TOP; int z_face = z_dir > 0 ? FACE_BACK : FACE_FRONT; int face = FACE_TOP; // Assumption is made that the camera is never outside the world while (IN_WORLD(x, y, z)) { // Determine if block is solid if (get_block(x, y, z) != BLOCK_AIR) { float dx = start.x - pos.x; float dy = start.y - pos.y; float dz = start.z - pos.z; float dist = dx*dx + dy*dy + dz*dz; vec3 relPos = pos; relPos.x -= x; relPos.y -= y; relPos.z -= z; // If hit info is requested, no color computation is done if (info != NULL) { int nx, ny, nz; face_normal(face, &nx, &ny, &nz); info->hit = true; info->x = x; info->y = y; info->z = z; info->nx = nx; info->ny = ny; info->nz = nz; info->dist = dist; return 0; } int tex = tex_index(relPos, face); return ray_color(x, y, z, pos, tex, face); } // Remaining distance inside this block given ray direction float dx = x - pos.x + dx_off; float dy = y - pos.y + dy_off; float dz = z - pos.z + dz_off; // Calculate distance for each dimension float t1 = dx / dir.x; float t2 = dy / dir.y; float t3 = dz / dir.z; // Find closest hit if (t1 <= t2 && t1 <= t3) { pos.x += dx; pos.y += t1 * dir.y; pos.z += t1 * dir.z; x += x_dir; face = x_face; } if (t2 <= t1 && t2 <= t3) { pos.x += t2 * dir.x; pos.y += dy; pos.z += t2 * dir.z; y += y_dir; face = y_face; } if (t3 <= t1 && t3 <= t2) { pos.x += t3 * dir.x; pos.y += t3 * dir.y; pos.z += dz; z += z_dir; face = z_face; } } nohit: if (info != NULL) { info->hit = false; } // Sky color return skyColor; }