| 113 | } |
| 114 | |
| 115 | void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t> &p_surface_indices) { |
| 116 | valid = false; |
| 117 | |
| 118 | ERR_FAIL_COND(p_surface_indices.size() && p_surface_indices.size() != p_faces.size()); |
| 119 | |
| 120 | int fc = p_faces.size(); |
| 121 | ERR_FAIL_COND(!fc || ((fc % 3) != 0)); |
| 122 | fc /= 3; |
| 123 | triangles.resize(fc); |
| 124 | |
| 125 | bvh.resize(fc * 3); ///< (@todo Make better) Will never be larger than this |
| 126 | BVH *bw = bvh.ptrw(); |
| 127 | |
| 128 | { |
| 129 | //create faces and indices and base bvh |
| 130 | //except for the Set for repeated triangles, everything |
| 131 | //goes in-place. |
| 132 | |
| 133 | const Vector3 *r = p_faces.ptr(); |
| 134 | const int32_t *si = p_surface_indices.ptr(); |
| 135 | Triangle *w = triangles.ptrw(); |
| 136 | HashMap<Vector3, int> db; |
| 137 | |
| 138 | for (int i = 0; i < fc; i++) { |
| 139 | Triangle &f = w[i]; |
| 140 | const Vector3 *v = &r[i * 3]; |
| 141 | |
| 142 | for (int j = 0; j < 3; j++) { |
| 143 | int vidx = -1; |
| 144 | Vector3 vs = v[j].snappedf(0.0001); |
| 145 | HashMap<Vector3, int>::Iterator E = db.find(vs); |
| 146 | if (E) { |
| 147 | vidx = E->value; |
| 148 | } else { |
| 149 | vidx = db.size(); |
| 150 | db[vs] = vidx; |
| 151 | } |
| 152 | |
| 153 | f.indices[j] = vidx; |
| 154 | if (j == 0) { |
| 155 | bw[i].aabb.position = vs; |
| 156 | } else { |
| 157 | bw[i].aabb.expand_to(vs); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | f.normal = Face3(r[i * 3 + 0], r[i * 3 + 1], r[i * 3 + 2]).get_plane().get_normal(); |
| 162 | f.surface_index = si ? si[i] : 0; |
| 163 | |
| 164 | bw[i].left = -1; |
| 165 | bw[i].right = -1; |
| 166 | bw[i].face_index = i; |
| 167 | bw[i].center = bw[i].aabb.get_center(); |
| 168 | } |
| 169 | |
| 170 | vertices.resize(db.size()); |
| 171 | Vector3 *vw = vertices.ptrw(); |
| 172 | for (const KeyValue<Vector3, int> &E : db) { |