| 81 | } |
| 82 | |
| 83 | void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb) { |
| 84 | if (p_level == cell_subdiv) { |
| 85 | //plot the face by guessing its albedo and emission value |
| 86 | |
| 87 | //find best axis to map to, for scanning values |
| 88 | int closest_axis = 0; |
| 89 | real_t closest_dot = 0; |
| 90 | |
| 91 | Plane plane = Plane(p_vtx[0], p_vtx[1], p_vtx[2]); |
| 92 | Vector3 normal = plane.normal; |
| 93 | |
| 94 | for (int i = 0; i < 3; i++) { |
| 95 | Vector3 axis; |
| 96 | axis[i] = 1.0; |
| 97 | real_t dot = Math::abs(normal.dot(axis)); |
| 98 | if (i == 0 || dot > closest_dot) { |
| 99 | closest_axis = i; |
| 100 | closest_dot = dot; |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | Vector3 axis; |
| 105 | axis[closest_axis] = 1.0; |
| 106 | Vector3 t1; |
| 107 | t1[(closest_axis + 1) % 3] = 1.0; |
| 108 | Vector3 t2; |
| 109 | t2[(closest_axis + 2) % 3] = 1.0; |
| 110 | |
| 111 | t1 *= p_aabb.size[(closest_axis + 1) % 3] / real_t(color_scan_cell_width); |
| 112 | t2 *= p_aabb.size[(closest_axis + 2) % 3] / real_t(color_scan_cell_width); |
| 113 | |
| 114 | Color albedo_accum; |
| 115 | Color emission_accum; |
| 116 | Vector3 normal_accum; |
| 117 | |
| 118 | float alpha = 0.0; |
| 119 | |
| 120 | //map to a grid average in the best axis for this face |
| 121 | for (int i = 0; i < color_scan_cell_width; i++) { |
| 122 | Vector3 ofs_i = real_t(i) * t1; |
| 123 | |
| 124 | for (int j = 0; j < color_scan_cell_width; j++) { |
| 125 | Vector3 ofs_j = real_t(j) * t2; |
| 126 | |
| 127 | Vector3 from = p_aabb.position + ofs_i + ofs_j; |
| 128 | Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis]; |
| 129 | Vector3 half = (to - from) * 0.5; |
| 130 | |
| 131 | //is in this cell? |
| 132 | if (!Geometry3D::triangle_box_overlap(from + half, half, p_vtx)) { |
| 133 | continue; //face does not span this cell |
| 134 | } |
| 135 | |
| 136 | //go from -size to +size*2 to avoid skipping collisions |
| 137 | Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis]; |
| 138 | Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2; |
| 139 | |
| 140 | if (normal.dot(ray_from - ray_to) < 0) { |
nothing calls this directly
no test coverage detected