void AABBQuery(TOctreeNode node, TVector <int> result, TAABB aabb) { if (node.is_end != -1) { result.Add(items[node.is_end]); } else { int i, k, t; for (i = 0; i < 2; i++) { if ((aabb.Get(0, i) < (node.dims.Get(0, 0) + node.dims.Get(0, 1)) * 0.5) != (i == 1)) { for (k = 0; k < 2; k++) { if ((aabb.Get(1, k) < (node.dims.Get(1, 0) + node.dims.Get(1, 1)) * 0.5) != (k == 1)) { for (t = 0; t < 2; t++) { if ((aabb.Get(2, t) < (node.dims.Get(2, 0) + node.dims.Get(2, 1)) * 0.5) != (t == 1)) { if (node.GetChild(i, k, t) != -1) { AABBQuery(nodes[node.GetChild(i, k, t)], result, aabb); } } } } } } } } }
public void Add(TAABB use_dims, int data) { if (use_dims.Overlaps(nodes[root].dims)) { Add(nodes[root], use_dims, data); } }
public void Extend(TAABB v) { bool need_change = false; if (v.max_x > max_x) { need_change = true; max_x = v.max_x; } if (v.min_x < min_x) { need_change = true; min_x = v.min_x; } if (v.max_y > max_y) { need_change = true; max_y = v.max_y; } if (v.min_y < min_y) { need_change = true; min_y = v.min_y; } if (v.max_z > max_z) { need_change = true; max_z = v.max_z; } if (v.min_z < min_z) { need_change = true; min_z = v.min_z; } if (need_change) { InitPosWidth(); } }
public TOctree(float use_min_node_size, TAABB use_dims) { nodes = new TIndexedVector <TOctreeNode>(1000); items = new TIndexedVector <TVector <int> >(1000); min_node_size = use_min_node_size; root = nodes.New(); Init(root, use_dims); }
public TAABB GetTriAABB(int tri) { TAABB result = new TAABB(pos[triangle[tri].p0], new Vector3(0, 0, 0)); result.Extend(pos[triangle[tri].p1]); result.Extend(pos[triangle[tri].p2]); return(result); }
public void AABBQuery(TVector <int> result, TAABB aabb) { result.Pop(result.Length); if (aabb.Overlaps(nodes[root].dims)) { AABBQuery(nodes[root], result, aabb); } DeleteRepeatingValues(result); }
public bool Overlaps(TAABB use_aabb) { for (int i = 0; i < 3; i++) { if (NotOverlay(Get(i, 0), Get(i, 1), use_aabb.Get(i, 0), use_aabb.Get(i, 1))) { return(false); } } return(true); }
void Init(int node, TAABB use_dims) { TOctreeNode new_node = new TOctreeNode(); new_node.dims = use_dims; if ((new_node.dims.Get(0, 1) - new_node.dims.Get(0, 0)) < min_node_size * 2) { new_node.is_end = items.New(); items[new_node.is_end] = new TVector <int>(5); } nodes[node] = new_node; }
void Add(TOctreeNode node, TAABB use_dims, int data) { if (node.is_end != -1) { for (int i = 0; i <= items[node.is_end].High; i++) { if (items[node.is_end][i] == data) { Debug.Assert(false); //в узле дерева не должно быть повторяющихся значений } } items[node.is_end].Add(data); } else { int i, k, t; for (i = 0; i < 2; i++) { if ((use_dims.Get(0, i) < (node.dims.Get(0, 0) + node.dims.Get(0, 1)) * 0.5) != (i == 1)) { for (k = 0; k < 2; k++) { if ((use_dims.Get(1, k) < (node.dims.Get(1, 0) + node.dims.Get(1, 1)) * 0.5) != (k == 1)) { for (t = 0; t < 2; t++) { if ((use_dims.Get(2, t) < (node.dims.Get(2, 0) + node.dims.Get(2, 1)) * 0.5) != (t == 1)) { if (node.GetChild(i, k, t) == -1) { node.SetChild(i, k, t, nodes.New()); TAABB temp = node.dims; temp.ToSubCube(i, k, t); Init(node.GetChild(i, k, t), temp); } Add(nodes[node.GetChild(i, k, t)], use_dims, data); } } } } } } } }
void Del(TOctreeNode node, TAABB use_dims, int data) { if (node.is_end != -1) { bool found = false; for (int i = 0; i <= items[node.is_end].High; i++) { if (items[node.is_end][i] == data) { found = true; items[node.is_end].Del(i); break; } } if (!found) { Debug.Assert(false); //значение должно присутствовать } } else { int i, k, t; for (i = 0; i < 2; i++) { if ((use_dims.Get(0, i) < (node.dims.Get(0, 0) + node.dims.Get(0, 1)) * 0.5) != (i == 1)) { //TODO из-за погрешностей вычислений могут возникнуть проблемы в void Del(TOctreeNode node, TAABB use_dims, int data) for (k = 0; k < 2; k++) { if ((use_dims.Get(1, k) < (node.dims.Get(1, 0) + node.dims.Get(1, 1)) * 0.5) != (k == 1)) { for (t = 0; t < 2; t++) { if ((use_dims.Get(2, t) < (node.dims.Get(2, 0) + node.dims.Get(2, 1)) * 0.5) != (t == 1)) { Del(nodes[node.GetChild(i, k, t)], use_dims, data); } } } } } } } }
public void RebuildGeometry() { //need_props_refresh = true;//TODO если обновлять окно свойст здесь, то почему-то не происходит перерисовка моделей int last_high = -1, normal_offset = 0, pos_offset = 0, color_offset = 0; if (objects.Count < 1) { return; } TTriMeshWithTree[] meshes = new TTriMeshWithTree[objects.Count]; TTriMesh[] not_cutted_meshes = new TTriMesh[meshes.Length]; float node_size = 0; TVector <int> buffer = new TVector <int>(1000); TAABB scene_box = new TAABB(); for (int i = 0; i < meshes.Length; i++) { not_cutted_meshes[i] = objects[i].GetTransformedMesh(); meshes[i] = new TTriMeshWithTree(not_cutted_meshes[i].GetCopy()); node_size += meshes[i].GetAverageTriSize(); if (i == 0) { scene_box = meshes[i].GetAABB(); } else { scene_box.Extend(meshes[i].GetAABB()); } } node_size /= meshes.Length; scene = new TTriMeshWithTree(node_size * 2, scene_box); TVector <int> query_result = new TVector <int>(1000); TVector <int> query_result1 = new TVector <int>(1000); for (int i = 0; i < meshes.Length; i++) { if (i != 0) { //сечём треугольники объекта треугольниками сцены scene.AABBQuery(query_result, meshes[i].GetAABB()); for (int k = 0; k <= query_result.High; k++) { meshes[i].Cut(buffer, scene.GetMesh(), query_result[k], scene.GetMesh().GetTriAABB(query_result[k])); } //сечём треугольники сцены треугольниками объекта(треугольники объекта не сечённые) for (int k = 0; k <= not_cutted_meshes[i].triangle.High; k++) { scene.Cut(buffer, not_cutted_meshes[i], k, not_cutted_meshes[i].GetTriAABB(k)); } scene.TrianglesInMeshQuery(buffer, query_result, meshes[i], true); meshes[i].TrianglesInMeshQuery(buffer, query_result1, scene, false); scene.DelTriangles(query_result); meshes[i].DelTriangles(query_result1); meshes[i].InverseNormals(); } //добавляем объект в сцену scene.Add(meshes[i]); } }
public TOBB(Vector3 use_pos, Vector3 use_widths) { aabb = new TAABB(use_pos, use_widths); orient = Matrix.Identity; }