private void InitTriangleInfoDic()
 {
     MeshFilter[] meshFilters = this.transform.GetComponentsInChildren <MeshFilter>();
     foreach (MeshFilter filter in meshFilters)
     {
         objDic.Add(filter.gameObject, IntersectionTest.GetTriangles(filter));
     }
 }
    private void IntersectTest()
    {
#if UNITY_EDITOR
        GameObject go;

        // -- for debug
        Stopwatch   stopwatch      = Stopwatch.StartNew();
        int         objIndex       = 0;
        int         intersectCount = 0;
        List <Task> tasks          = new List <Task>();
        foreach (KeyValuePair <GameObject, TriangleInfo[]> pair in objDic)
        {
            if (pair.Value == null)
            {
                continue;
            }
            // 每个物体多线程相交测试
            if (enableMultiThreading)
            {
                tasks.Add(Task.Factory.StartNew(MultiThreadingIntersectTest, new ObjInfo(pair)));
                continue;
            }
            // 单线程相交
            objIndex++;
            intersectCount = 0;
            go             = pair.Key;
            Bounds       bound  = go.GetComponent <Renderer>().bounds;
            AABBBoundBox objBox = new AABBBoundBox(bound.min, bound.max);
            var          l      = octree.GetIntersections(objBox);
            for (int i = 0; i < l.Count; i++)
            {
                foreach (TriangleInfo tInfo in pair.Value)
                {
                    if (l[i].overlapWithTriangle)
                    {
                        continue;
                    }
                    if (IntersectionTest.AABBTriangle(l[i].boundBox, tInfo))
                    {
                        l[i].overlapWithTriangle = true;
                    }
                }
                intersectCount++;
                bool cancel = EditorUtility.DisplayCancelableProgressBar("Voxelize", $"No.{objIndex} Object (of {objDic.Count}), Intersect Count {intersectCount}/{l.Count}",
                                                                         (float)intersectCount / l.Count);
                if (cancel)
                {
                    break;
                }
            }
        }
        Task.WaitAll(tasks.ToArray());
        stopwatch.Stop();
        EditorUtility.ClearProgressBar();
        Debug.Log($"体素化完成,耗时:{stopwatch.ElapsedMilliseconds}ms");
#endif
    }
Beispiel #3
0
    private void IntersectTestDivide(object obj)
    {
        Tuple <int, int, int> indexTuple = (Tuple <int, int, int>)obj;
        int startX = indexTuple.Item1;
        int startY = indexTuple.Item2;
        int startZ = indexTuple.Item3;
        int xRange = startX + divide;
        int yRange = startY + divide;
        int zRange = startZ + divide;

        xRange = xRange < _xMax ? xRange : _xMax;
        yRange = yRange < _yMax ? yRange : _yMax;
        zRange = zRange < _zMax ? zRange : _zMax;

        #region Naive Simple Violent Loop...
        for (int x = startX; x < xRange; x++)
        {
            for (int y = startY; y < yRange; y++)
            {
                for (int z = startZ; z < zRange; z++)
                {
                    if (_voxels[x, y, z])
                    {
                        continue;
                    }
                    AABBBoundBox         boundBox          = new AABBBoundBox(GetVoxelBoundMin(x, y, z), GetVoxelBoundMax(x, y, z));
                    List <TriangleBound> triangleBoundList = _octree.GetIntersections(boundBox);

                    for (int i = 0; i < triangleBoundList.Count; i++)
                    {
                        for (int j = 0; j < triangleBoundList[i].triangles.Length; j++)
                        {
                            if (IntersectionTest.AABBTriangle(boundBox, triangleBoundList[i].triangles[j]))
                            {
                                _voxels[x, y, z] = true;
                            }
                        }
                    }
                }
            }
        }
        #endregion

        lock (_locker)
        {
            _completeCount++;
        }
    }
Beispiel #4
0
 //检测碰撞
 private void CollisionDetection()
 {
     for (int i = 0; i < spheres.Length; ++i)
     {
         if (curBall == i)
         {
             continue;
         }
         if (IntersectionTest.Check_Sphere_Sphere(spheres[i].Sphere, spheres[curBall].Sphere))
         {
             spheresVelocity[i]      += spheresVelocity[curBall];
             spheresVelocity[curBall] = Vector3.zero;
             curBall = i;
             break;
         }
     }
 }
    void MultiThreadingIntersectTest(object p)
    {
        ObjInfo info = (ObjInfo)p;
        var     l    = octree.GetIntersections(info.boundBox);

        for (int i = 0; i < l.Count; i++)
        {
            foreach (TriangleInfo tInfo in info.triangles)
            {
                if (l[i].overlapWithTriangle)
                {
                    continue;
                }
                if (IntersectionTest.AABBTriangle(l[i].boundBox, tInfo))
                {
                    l[i].overlapWithTriangle = true;
                }
            }
        }
        Debug.Log($"Thread complete : {Thread.CurrentThread.ManagedThreadId}");
    }
Beispiel #6
0
 private void SimpleCollisionDetection()
 {
     for (int i = 0; i < spheres.Count; ++i)
     {
         for (int j = 0; j < aabbs.Count; ++j)
         {
             if (spheres[i].HasCheckedAABB == aabbs[j])
             {
                 continue;
             }
             Vector3 closestPt;
             if (IntersectionTest.Check_Sphere_AABB(spheres[i].sphere, aabbs[j], out closestPt))
             {
                 CollisionDetection.Plane p = aabbs[j].GetClosestPlane(spheres[i].sphere.center);
                 Vector3 noraml             = p.normal;
                 Vector3 v = spheres[i].Rigidbody.velocity;
                 v = Vector3.Reflect(v, noraml);
                 spheres[i].Rigidbody.velocity = v * 0.9f;
                 spheres[i].HasCheckedAABB     = aabbs[j];
             }
         }
         for (int k = 0; k < spheres.Count; ++k)
         {
             if (k == i)
             {
                 continue;
             }
             if (spheres[i].HasCheckedSphere == spheres[k])
             {
                 continue;
             }
             if (IntersectionTest.Check_Sphere_Sphere(spheres[i].sphere, spheres[k].sphere))
             {
                 spheres[i].Rigidbody.velocity = -spheres[i].Rigidbody.velocity * 0.9f;
                 spheres[i].HasCheckedSphere   = spheres[k];
             }
         }
     }
 }
Beispiel #7
0
            private void HandleDynamicVsHeightMapCollision(
                DynamicCollider dynCollider,
                HeightMapCollider hMapCollider,
                List <Contact> contacts,
                List <Segment> coarseContacts)
            {
                // position of bounding sphere in world coordinates
                Vector3 spherePos = dynCollider.BoundingSphere.CenterW;
                float   radius    = dynCollider.BoundingSphere.Radius;

                // filtering the triangle grid with the sphere projection
                hMapCollider.TriGrid.FilterBySphereProjection(spherePos, radius);

                foreach (Triangle tri in hMapCollider.TriGrid)
                {
                    Vector3Int ind = hMapCollider.TriGrid.CurrentIndices;

                    colors[ind.x] = colors[ind.y] = colors[ind.z] = Color.blue;

                    if (IntersectionTest.SphereVsTriangle(spherePos, radius, tri))
                    {
                        if (dynCollider is CSACollider)
                        {
                            // curves vs triangle
                        }
                        else if (dynCollider is BruteForceCollider)
                        {
                            // triangles vs triangle
                        }
                        else if (dynCollider is VertexCollider)
                        {
                            // vertices vs triangle
                        }
                    }
                }
            }
Beispiel #8
0
            private void HandleCSAVsHeightMapCollision(
                CSACollider csaCollider,
                HeightMapCollider hMapCollider,
                List <Contact> contacts,
                List <Segment> coarseContacts
                )
            {
                foreach (Triangle tri in hMapCollider.TriGrid)
                {
                    Vector3Int ind = hMapCollider.TriGrid.CurrentIndices;

                    // position of bounding sphere in world coordinates
                    Vector3 spherePos = csaCollider.BoundingSphere.CenterW;
                    float   radius    = csaCollider.BoundingSphere.Radius;

                    colors[ind.x] = colors[ind.y] = colors[ind.z] = Color.blue;

                    if (IntersectionTest.SphereVsTriangle(spherePos, radius, tri))
                    {
                        colors[ind.x] = colors[ind.y] = colors[ind.z] = Color.red;

                        Diagnostics.Tic();
                        foreach (Slice slice in csaCollider.Slices)
                        {
                            if (IntersectionTest.PlaneVsTriangle(slice, tri, out Vector3 vec1, out Vector3 vec2))
                            {
                                // endpoints of the plane-triangle intersection in plane local coordinates
                                Vector2 vecA = slice.TransformToLocalBase(vec1);
                                Vector2 vecB = slice.TransformToLocalBase(vec2);

                                // calculating the data for transforming the curve
                                float       theta       = Mathf.Atan2(vecB.y - vecA.y, vecB.x - vecA.x);
                                Complex     segRotation = new Complex(theta);
                                Transform2D segTrf      = new Transform2D(-vecA, segRotation);
                                float       segLength   = Vector2.Distance(vecA, vecB);

                                Vector2 upInLocal = slice.TransformToLocalBase(vec1 + tri.Normal);

                                foreach (FourierCurve curve in slice.curves)
                                {
                                    if (IntersectionTest.SegmentVsRectangle(curve.AABB, segTrf, segLength))
                                    {
                                        // add the segments to render on the scene
                                        debugSegments.Add(new Segment(vec1, vec2));
                                        coarseContacts.Add(new Segment(vec1, vec2));

                                        if (csaCollider.rootFinder == CSACollider.RootFinder.SimulatedAnnealing)
                                        {
                                            if (IntersectionTest.SegmentVsCurveSA(
                                                    curve,
                                                    vecA,
                                                    vecB,
                                                    segLength,
                                                    segRotation,
                                                    upInLocal,
                                                    out Vector2 contactInPlaneLocal,
                                                    out float penetration,
                                                    annealingTemperature,
                                                    penetrationLimit))
                                            {
                                                // rotate back the contact point into world coordinates
                                                Vector3 contactInWorld = contactInPlaneLocal.x * slice.LocalX + contactInPlaneLocal.y * slice.LocalY + slice.RefPoint;

                                                debugPoints.Add(contactInWorld);
                                                segmentColor.Add(Color.green);

                                                // the contact point relative to the object's transform
                                                Vector3 contactInLocal = contactInPlaneLocal.x * slice.LocalXL + contactInPlaneLocal.y * slice.LocalYL;

                                                RigidBody body = csaCollider.GetComponent <RigidBody>();
                                                if (!csaCollider.isTrigger && body != null && body.enabled)
                                                {
                                                    contacts.Add(new Contact(tri, contactInWorld, body));
                                                }
                                            }
                                            else
                                            {
                                                segmentColor.Add(Color.magenta);
                                            }
                                        }
                                        else if (csaCollider.rootFinder == CSACollider.RootFinder.AberthEhrlich)
                                        {
                                            List <Vector2> intersections = new List <Vector2>();
                                            if (IntersectionTest.SegmentVsCurveAE(
                                                    curve,
                                                    vecA,
                                                    vecB,
                                                    segLength,
                                                    segRotation,
                                                    upInLocal,
                                                    intersections))
                                            {
                                                foreach (Vector2 intPlane in intersections)
                                                {
                                                    Vector3 intInWorld = intPlane.x * slice.LocalX + intPlane.y * slice.LocalY + slice.RefPoint;
                                                    debugPoints.Add(intInWorld);
                                                    segmentColor.Add(Color.green);

                                                    RigidBody body = csaCollider.GetComponent <RigidBody>();
                                                    if (!csaCollider.isTrigger && body != null && body.enabled)
                                                    {
                                                        contacts.Add(new Contact(tri, intInWorld, body));
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                segmentColor.Add(Color.magenta);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        Diagnostics.Toc2Log("slice time");
                    }
                }