public static List <Model3d> Query(OctreeNode node, AABB3d aabb) { //std::vector<Model*> result; List <Model3d> result = new List <Model3d>(); if (IntersectionTest3D.AABB3dWithAABB3d(aabb, node.m_bounds)) { if (node.m_children == null) { for (int i = 0, size = node.m_models.Count; i < size; ++i) { OBB3d bounds = node.m_models[i].GetOBB(); if (IntersectionTest3D.AABB3dWithOBB3d(aabb, bounds)) { result.Add(node.m_models[i]); } } } else { for (int i = 0; i < 8; ++i) { List <Model3d> child = Query(node.m_children[i], aabb); if (child.Count > 0) { //result.insert(result.end(), child.begin(), child.end()); result.AddRange(child); } } } } return(result); }
public OBB3d GetOBB() { Matrix4x4L obj2World = GetObj2WorldMatrix(); OBB3d obb = new OBB3d(obj2World * m_aabb.m_pos, m_rotation, m_aabb.m_size.x, m_aabb.m_size.y, m_aabb.m_size.z); return(obb); }
public static bool IsIntersction3d(HitShape3dData hitData, OBB3d obb) { if (hitData.m_type == HitShape3dType.Sphere) { //Sphere3d hitSphere = new Sphere3d(hitData.m_pos, hitData.m_radius); return(IntersectionTest3D.Sphere3dWithObb3d(hitData.m_sphere, obb)); } else if (hitData.m_type == HitShape3dType.OBB) { //OBB3d obb2 = new OBB3d(hitData.m_pos, hitData.m_rotation, hitData.m_size); return(IntersectionTest3D.OBB3dWithOBB3d(obb, hitData.m_obb)); } else { return(false); } }
public static void SplitTree(OctreeNode node, int depth) { if (depth-- <= 0) { // Decrements depth return; } if (node.m_children == null) { node.m_children = new OctreeNode[8]; Vector3L c = node.m_bounds.m_pos; Vector3L e = node.m_bounds.GetHalfSize() * 0.5f; node.m_children[0].m_bounds = new AABB3d(c + new Vector3L(-e.x, +e.y, -e.z), node.m_bounds.GetHalfSize()); node.m_children[1].m_bounds = new AABB3d(c + new Vector3L(+e.x, +e.y, -e.z), node.m_bounds.GetHalfSize()); node.m_children[2].m_bounds = new AABB3d(c + new Vector3L(-e.x, +e.y, +e.z), node.m_bounds.GetHalfSize()); node.m_children[3].m_bounds = new AABB3d(c + new Vector3L(+e.x, +e.y, +e.z), node.m_bounds.GetHalfSize()); node.m_children[4].m_bounds = new AABB3d(c + new Vector3L(-e.x, -e.y, -e.z), node.m_bounds.GetHalfSize()); node.m_children[5].m_bounds = new AABB3d(c + new Vector3L(+e.x, -e.y, -e.z), node.m_bounds.GetHalfSize()); node.m_children[6].m_bounds = new AABB3d(c + new Vector3L(-e.x, -e.y, +e.z), node.m_bounds.GetHalfSize()); node.m_children[7].m_bounds = new AABB3d(c + new Vector3L(+e.x, -e.y, +e.z), node.m_bounds.GetHalfSize()); } if (node.m_children != null && node.m_models.Count > 0) { for (int i = 0; i < 8; ++i) { // For each child for (int j = 0, size = node.m_models.Count; j < size; ++j) { OBB3d obb = node.m_models[j].GetOBB(); if (IntersectionTest3D.AABB3dWithOBB3d(node.m_children[i].m_bounds, obb)) { node.m_children[i].m_models.Add(node.m_models[j]); } } } node.m_models.Clear(); // Recurse for (int i = 0; i < 8; ++i) { SplitTree(node.m_children[i], depth); } } }
public static void Insert(OctreeNode node, Model3d model) { OBB3d bounds = model.GetOBB(); if (IntersectionTest3D.AABB3dWithOBB3d(node.m_bounds, bounds)) { if (node.m_children == null) { node.m_models.Add(model); } else { for (int i = 0; i < 8; ++i) { Insert(node.m_children[i], model); } } } }
public List <Model3d> Query(AABB3d aabb) { if (m_octree != null) { // :: lets the compiler know to look outside class scope return(Octree3d.Query(m_octree, aabb)); } List <Model3d> result = new List <Model3d>(); for (int i = 0, size = m_modleList.Count; i < size; ++i) { OBB3d bounds = m_modleList[i].GetOBB(); if (IntersectionTest3D.AABB3dWithOBB3d(aabb, bounds)) { result.Add(m_modleList[i]); } } return(result); }
public static Vector3L ClosestPointOfPoint3dWithOBB3d(Vector3L point, OBB3d obb) { //Vector3L objMin = obb.GetAABBMin(); //Vector3L objMax = obb.GetAABBMax(); Matrix4x4L obj2World = obb.GetObjToWorld(); Matrix4x4L worldToObj = obj2World.inverse; Vector3L objMin = (Vector3L)(worldToObj * obb.m_pos) - obb.GetHalfSize(); Vector3L objMax = (Vector3L)(worldToObj * obb.m_pos) + obb.GetHalfSize(); Vector3L objPoint = worldToObj * point; Vector3L objResult = objPoint; objResult.x = (objResult.x < objMin.x) ? objMin.x : objResult.x; objResult.y = (objResult.y < objMin.x) ? objMin.y : objResult.y; objResult.z = (objResult.z < objMin.x) ? objMin.z : objResult.z; objResult.x = (objResult.x > objMax.x) ? objMax.x : objResult.x; objResult.y = (objResult.y > objMax.x) ? objMax.y : objResult.y; objResult.z = (objResult.z > objMax.x) ? objMax.z : objResult.z; Vector3L worldResult = obj2World * objResult; return(worldResult); }
public List <Model3d> CullByFrustum(Frustum3d frustum) { List <Model3d> result = new List <Model3d>(); foreach (var iter in m_modleList) { iter.m_cullFlag = false; } if (m_octree == null) { foreach (var iter in m_modleList) { OBB3d bounds = iter.GetOBB(); if (IntersectionTest3D.Frustum3dWithOBB3d(frustum, bounds)) { result.Add(iter); } } } else { List <OctreeNode> nodes = new List <OctreeNode>(); nodes.Add(m_octree); while (nodes.Count > 0) { OctreeNode active = nodes[0]; nodes.RemoveAt(0); if (active.m_children != null) { // Has child nodes for (int i = 0; i < 8; ++i) { AABB3d bounds = active.m_children[i].m_bounds; if (IntersectionTest3D.Frustum3dWithAABB3d(frustum, bounds)) { nodes.Add(active.m_children[i]); } } } else { // Is leaf node for (int i = 0; i < active.m_models.Count; ++i) { if (!active.m_models[i].m_cullFlag) { OBB3d bounds = active.m_models[i].GetOBB(); if (IntersectionTest3D.Frustum3dWithOBB3d(frustum, bounds)) { active.m_models[i].m_cullFlag = true; result.Add(active.m_models[i]); } } } } } } return(result); }