Example #1
0
    public static Vector3L ClosestPointOfPoint3dWithTriangle3d(Triangle3d t, Vector3L p)
    {
        Plane3d  plane   = FromTriangle(t);
        Vector3L closest = ClosestPointOfPoint3dWithPlane3d(p, plane);

        // Closest point was inside triangle
        if (IntersectionTest3D.Point3dWithTriangle(closest, t))
        {
            return(closest);
        }

        Vector3L c1 = ClosestPointOfPoint3dWithSegment3d(closest, new Segment3d(t.m_point0, t.m_point1)); // Line AB
        Vector3L c2 = ClosestPointOfPoint3dWithSegment3d(closest, new Segment3d(t.m_point1, t.m_point2)); // Line BC
        Vector3L c3 = ClosestPointOfPoint3dWithSegment3d(closest, new Segment3d(t.m_point2, t.m_point0)); // Line CA

        FloatL magSq1 = (closest - c1).sqrMagnitude;
        FloatL magSq2 = (closest - c2).sqrMagnitude;
        FloatL magSq3 = (closest - c3).sqrMagnitude;

        if (magSq1 < magSq2 && magSq1 < magSq3)
        {
            return(c1);
        }
        else if (magSq2 < magSq1 && magSq2 < magSq3)
        {
            return(c2);
        }

        return(c3);
    }
Example #2
0
    public Model3d Raycast(Ray3d ray)
    {
        if (m_octree != null)
        {
            // :: lets the compiler know to look outside class scope
            return(Octree3d.Raycast(m_octree, ray));
        }

        Model3d result   = null;
        FloatL  result_t = -1;

        for (int i = 0, size = m_modleList.Count; i < size; ++i)
        {
            FloatL t = IntersectionTest3D.Ray3dWithModel3d(ray, m_modleList[i]);
            if (result == null && t >= 0)
            {
                result   = m_modleList[i];
                result_t = t;
            }
            else if (result != null && t < result_t)
            {
                result   = m_modleList[i];
                result_t = t;
            }
        }

        return(result);
    }
Example #3
0
    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);
    }
Example #4
0
    public static Model3d Raycast(OctreeNode node, Ray3d ray)
    {
        IntersectionTest3D.RaycastResult raycast = new IntersectionTest3D.RaycastResult();
        IntersectionTest3D.Ray3dWithAABB3d(node.m_bounds, ray, ref raycast);
        FloatL t = raycast.m_t;

        if (t >= 0)
        {
            if (node.m_children == null)
            {
                return(FindClosest(node.m_models, ray));
            }
            else
            {
                /*std::vector<Model*> results;*/
                List <Model3d> results = new List <Model3d>();
                for (int i = 0; i < 8; ++i)
                {
                    Model3d result = Raycast(node.m_children[i], ray);
                    if (result != null)
                    {
                        results.Add(result);
                    }
                }
                return(FindClosest(results, ray));
            }
        }

        return(null);
    }
Example #5
0
    public static Model3d FindClosest(List <Model3d> set, Ray3d ray)
    {
        if (set.Count == 0)
        {
            return(null);
        }

        Model3d closest   = null;
        FloatL  closest_t = -1;

        for (int i = 0, size = set.Count; i < size; ++i)
        {
            FloatL this_t = IntersectionTest3D.Ray3dWithModel3d(ray, set[i]);

            if (this_t < 0)
            {
                continue;
            }

            if (closest_t < 0 || this_t < closest_t)
            {
                closest_t = this_t;
                closest   = set[i];
            }
        }

        return(closest);
    }
 public static bool IsIntersction3d(HitShape3dData hitData, Segment3d segment)
 {
     if (hitData.m_type == HitShape3dType.Sphere)
     {
         //Sphere3d hitSphere = new Sphere3d(hitData.m_pos, hitData.m_radius);
         return(IntersectionTest3D.Segment3dWithSphere3d(segment, hitData.m_sphere));
     }
     else if (hitData.m_type == HitShape3dType.OBB)
     {
         //OBB3d obb = new OBB3d(hitData.m_pos, hitData.m_rotation, hitData.m_size);
         return(IntersectionTest3D.Segment3dWithOBB3d(segment, hitData.m_obb));
     }
     else
     {
         return(false);
     }
 }
Example #7
0
    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);
            }
        }
    }
Example #8
0
    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);
                }
            }
        }
    }
Example #9
0
    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 bool IsIntersction3d(HitShape3dData hitData1, HitShape3dData hitData2)
 {
     if (hitData1.m_type == HitShape3dType.Sphere && hitData2.m_type == HitShape3dType.Sphere)
     {
         return(IntersectionTest3D.Sphere3dWithSphere3d(hitData1.m_sphere, hitData2.m_sphere));
     }
     else if (hitData1.m_type == HitShape3dType.Sphere && hitData2.m_type == HitShape3dType.OBB)
     {
         return(IntersectionTest3D.Sphere3dWithObb3d(hitData1.m_sphere, hitData2.m_obb));
     }
     else if (hitData1.m_type == HitShape3dType.OBB && hitData2.m_type == HitShape3dType.Sphere)
     {
         return(IntersectionTest3D.Sphere3dWithObb3d(hitData2.m_sphere, hitData1.m_obb));
     }
     else if (hitData1.m_type == HitShape3dType.OBB && hitData2.m_type == HitShape3dType.OBB)
     {
         return(IntersectionTest3D.OBB3dWithOBB3d(hitData2.m_obb, hitData1.m_obb));
     }
     else
     {
         return(false);
     }
 }
Example #11
0
    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);
    }
    static void SplitBVHNode(BVHNode node, Mesh3d model, int depth)
    {
        if (depth-- <= 0)       // Decrements depth
        {
            return;
        }

        if (node.m_children == null)
        {
            // Only split if this node contains triangles
            if (node.m_triangles.Count > 0)
            {
                node.m_children = new BVHNode[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 this node was just split
        if (node.m_children != null && node.m_triangles.Count > 0)
        {
            for (int i = 0; i < 8; ++i)
            { // For each child
                // Count how many triangles each child will contain
                //node.m_children[i].numTriangles = 0;
                for (int j = 0; j < node.m_triangles.Count; ++j)
                {
                    Triangle3d t = node.m_triangles[j];
                    if (IntersectionTest3D.Triangle3dWithAABB3d(t, node.m_children[i].m_bounds))
                    {
                        node.m_children[i].m_triangles.Add(t);
                    }
                }
//              if (node.children[i].numTriangles == 0) {
//                  continue;
//              }
//              node.children[i].triangles = new int[node.children[i].numTriangles];
//              int index = 0; // Add the triangles in the new child arrau
//              for (int j = 0; j < node.numTriangles; ++j)
//                 {
//                  Triangle t = model.triangles[node.triangles[j]];
//                  if (TriangleAABB(t, node.children[i].bounds)) {
//                      node.children[i].triangles[index++] = node.triangles[j];
//                  }
//              }
            }

            //node.numTriangles = 0;
            //delete[] node.triangles;
            node.m_triangles.Clear();

            // Recurse
            for (int i = 0; i < 8; ++i)
            {
                SplitBVHNode(node.m_children[i], model, depth);
            }
        }
    }