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); } } } } } } } } }
void RayQuery(TOctreeNode node, TVector <int> result, TRay ray) { if (node.is_end != -1) { result.Add(items[node.is_end]); } else { for (int i = 0; i < 8; i++) { if (node.child[i] != -1) { if (nodes[node.child[i]].dims.Overlaps(ray)) { RayQuery(nodes[node.child[i]], result, ray); } } } } }
void CutTriangleByPlane(TPlane plane, int tri) { TMeshTri t = triangle[tri]; float d0 = plane.DistToPlane(pos[t.p0]), d1 = plane.DistToPlane(pos[t.p1]), d2 = plane.DistToPlane(pos[t.p2]); bool d0_sign = d0 >= 0; bool d1_sign = d1 >= 0; bool d2_sign = d2 >= 0; int vert0 = -1, vert1 = -1, vert2 = -1; { int zero_count = 0; if (d0 == 0.0f) { zero_count++; } if (d1 == 0.0f) { zero_count++; } if (d2 == 0.0f) { zero_count++; } if (zero_count == 3 || zero_count == 2) { return; } } if (d0 == 0.0f || d1 == 0.0f || d2 == 0.0f) { float x = 0; if (d0 == 0.0f) { if (d1_sign == d2_sign) { return; } vert0 = 0; vert1 = 1; vert2 = 2; x = d1 / (d1 - d2); } else if (d1 == 0.0f) { if (d0_sign == d2_sign) { return; } vert0 = 1; vert1 = 2; vert2 = 0; x = d2 / (d2 - d0); } else// if (d2 == 0.0f) { if (d0_sign == d1_sign) { return; } vert0 = 2; vert1 = 0; vert2 = 1; x = d0 / (d0 - d1); } Vector3 new_pos = Blend(pos[t.GetPos(vert1)], pos[t.GetPos(vert2)], x); Vector3 new_normal = Blend(normal[t.GetNormal(vert1)], normal[t.GetNormal(vert2)], x); new_normal.Normalize(); Debug.Assert(!float.IsNaN(new_pos.X) && !float.IsNaN(new_pos.Y) && !float.IsNaN(new_pos.Z)); pos.Add(new_pos); normal.Add(new_normal); TMeshTri temp = triangle[tri]; triangle[tri] = new TMeshTri( temp.GetPos(vert0), temp.GetPos(vert1), pos.High, temp.GetNormal(vert0), temp.GetNormal(vert1), normal.High, 0, 0, 0); triangle.Add(new TMeshTri( temp.GetPos(vert0), pos.High, temp.GetPos(vert2), temp.GetNormal(vert0), normal.High, temp.GetNormal(vert2), 0, 0, 0)); } else { float x1 = 0, x2 = 0; if ((d0_sign == d1_sign) && (d0_sign != d2_sign)) { vert0 = 2; vert1 = 0; vert2 = 1; x1 = d2 / (d2 - d0); x2 = d2 / (d2 - d1); } else if ((d0_sign == d2_sign) && (d0_sign != d1_sign)) { vert0 = 1; vert1 = 2; vert2 = 0; x1 = d1 / (d1 - d2); x2 = d1 / (d1 - d0); } else if ((d1_sign == d2_sign) && (d0_sign != d1_sign)) { vert0 = 0; vert1 = 1; vert2 = 2; x1 = d0 / (d0 - d1); x2 = d0 / (d0 - d2); } else { return; //треугольники могут пересекаются из-за неточностей } Vector3 new_pos1 = Blend(pos[t.GetPos(vert0)], pos[t.GetPos(vert1)], x1); Vector3 new_pos2 = Blend(pos[t.GetPos(vert0)], pos[t.GetPos(vert2)], x2); Vector3 new_normal1 = Blend(normal[t.GetNormal(vert0)], normal[t.GetNormal(vert1)], x1); Vector3 new_normal2 = Blend(normal[t.GetNormal(vert0)], normal[t.GetNormal(vert2)], x2); new_normal1.Normalize(); new_normal2.Normalize(); pos.Add(new_pos1); pos.Add(new_pos2); Debug.Assert(!float.IsNaN(new_pos1.X) && !float.IsNaN(new_pos1.Y) && !float.IsNaN(new_pos1.Z)); Debug.Assert(!float.IsNaN(new_pos2.X) && !float.IsNaN(new_pos2.Y) && !float.IsNaN(new_pos2.Z)); normal.Add(new_normal1); normal.Add(new_normal2); TMeshTri temp = triangle[tri]; //TODO выбирать наиболее короткое ребро triangle[tri] = new TMeshTri( temp.GetPos(vert0), pos.High - 1, pos.High, temp.GetNormal(vert0), normal.High - 1, normal.High, 0, 0, 0); triangle.Add(new TMeshTri( pos.High - 1, temp.GetPos(vert1), temp.GetPos(vert2), normal.High - 1, temp.GetNormal(vert1), temp.GetNormal(vert2), 0, 0, 0)); triangle.Add(new TMeshTri( pos.High - 1, temp.GetPos(vert2), pos.High, normal.High - 1, temp.GetNormal(vert2), normal.High, 0, 0, 0)); } }
void GetNewSpace() { v.Add(); free_v.Add(v.High); }