Exemple #1
0
        public bool TryGetSceneNear(Vector3d position, bool onlyEnabled, out SceneInfo sceneInfo)
        {
            IScene[] scenes = null;
            if (m_sceneFactory != null)
            {
                scenes = m_sceneFactory.GetScenes();
            }

            IScene closestScene = null;
            double minDist      = Double.MaxValue;

            if (scenes != null)
            {
                for (int i = 0; i < scenes.Length; i++)
                {
                    IScene scene = scenes[i];

                    // Get the midpoint of this scene
                    Vector3d midpoint = (scene.MaxPosition + scene.MinPosition) * 0.5d;
                    // Compare this distance against the current minimum distance (squared, to avoid an unncessary sqrt)
                    double distance = Vector3d.DistanceSquared(position, midpoint);
                    if (distance < minDist)
                    {
                        minDist      = distance;
                        closestScene = scene;
                    }
                }
            }

            if (closestScene != null)
            {
                sceneInfo = SceneInfo.FromScene(closestScene);
                return(true);
            }

            sceneInfo = null;
            return(false);
        }
Exemple #2
0
        bool is_same_triangle(ref Vector3d a, ref Vector3d b, ref Vector3d c,
                              ref Vector3d x, ref Vector3d y, ref Vector3d z, double tolSqr)
        {
            if (a.DistanceSquared(x) < tolSqr)
            {
                if (b.DistanceSquared(y) < tolSqr && c.DistanceSquared(z) < tolSqr)
                {
                    return(true);
                }

                if (b.DistanceSquared(z) < tolSqr && c.DistanceSquared(y) < tolSqr)
                {
                    return(true);
                }
            }
            else if (a.DistanceSquared(y) < tolSqr)
            {
                if (b.DistanceSquared(x) < tolSqr && c.DistanceSquared(z) < tolSqr)
                {
                    return(true);
                }

                if (b.DistanceSquared(z) < tolSqr && c.DistanceSquared(x) < tolSqr)
                {
                    return(true);
                }
            }
            else if (a.DistanceSquared(z) < tolSqr)
            {
                if (b.DistanceSquared(x) < tolSqr && c.DistanceSquared(y) < tolSqr)
                {
                    return(true);
                }

                if (b.DistanceSquared(y) < tolSqr && c.DistanceSquared(x) < tolSqr)
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #3
0
 bool is_same_edge(ref Vector3d a, ref Vector3d b, ref Vector3d c, ref Vector3d d)
 {
     return((a.DistanceSquared(c) < merge_r2 && b.DistanceSquared(d) < merge_r2) ||
            (a.DistanceSquared(d) < merge_r2 && b.DistanceSquared(c) < merge_r2));
 }
Exemple #4
0
        public bool FindInBall(Vector3d pt, double r, int[] buffer, out int buffer_count)
        {
            buffer_count = 0;

            double   halfCell = CellSize * 0.5;
            Vector3i idx      = indexF.ToGrid(pt);
            Vector3d center   = indexF.FromGrid(idx) + halfCell * Vector3d.One;

            if (r > CellSize)
            {
                throw new ArgumentException("PointSetHashtable.FindInBall: large radius unsupported");
            }

            double r2 = r * r;

            // check all in this cell
            PointList center_cell = Grid.Get(idx, false);

            if (center_cell != null)
            {
                foreach (int vid in center_cell)
                {
                    if (pt.DistanceSquared(Points.GetVertex(vid)) < r2)
                    {
                        if (buffer_count == buffer.Length)
                        {
                            return(false);
                        }

                        buffer[buffer_count++] = vid;
                    }
                }
            }

            // if we are close enough to cell border we need to check nbrs
            // [TODO] could iterate over fewer cells here, if r is bounded by CellSize,
            // then we should only ever need to look at 3, depending on which octant we are in.
            if ((pt - center).MaxAbs + r > halfCell)
            {
                for (int ci = 0; ci < 26; ++ci)
                {
                    Vector3i ioffset = gIndices.GridOffsets26[ci];

                    // if we are within r from face, we need to look into it
                    var ptToFaceCenter = new Vector3d(
                        center.x + halfCell * ioffset.x - pt.x,
                        center.y + halfCell * ioffset.y - pt.y,
                        center.z + halfCell * ioffset.z - pt.z);
                    if (ptToFaceCenter.MinAbs > r)
                    {
                        continue;
                    }

                    PointList ncell = Grid.Get(idx + ioffset, false);
                    if (ncell != null)
                    {
                        foreach (int vid in ncell)
                        {
                            if (pt.DistanceSquared(Points.GetVertex(vid)) < r2)
                            {
                                if (buffer_count == buffer.Length)
                                {
                                    return(false);
                                }

                                buffer[buffer_count++] = vid;
                            }
                        }
                    }
                }
            }

            return(true);
        }
    public override void Selected(SelectionType button)
    {
        nullifyHitPos = true;
        transform.parent.SendMessage("Selected", button, SendMessageOptions.DontRequireReceiver);
        if (button == SelectionType.SELECTALL)
        {
            BlockMove = true;
        }
        else
        {
            MeshFilter mf   = GetComponent <MeshFilter>();
            Mesh       mesh = mf.sharedMesh;
            currentHit = transform.InverseTransformPoint(AppState.instance.lastHitPosition);
            Vector3d      target = currentHit;
            System.Random rand   = new System.Random();
            int           count  = 0;
            //
            // The algorithm will find local optima - repeat until you get the tru optima
            // but limit the interation using a count
            //
            Int32 current = 0;
            while (count < dmesh.VertexCount)
            {
                count++;
                //
                // choose a random starting point
                //
                current = rand.Next(0, dmesh.VertexCount);
                Vector3d vtx         = dmesh.GetVertex(current);
                double   currentDist = vtx.DistanceSquared(target);
                //
                // find the ring of triangles around the current point
                //
                int iter = 0;
                while (true)
                {
                    iter++;
                    //    throw new InvalidOperationException("Meh One Ring operation invalid : " + res.ToString());
                    //
                    // Interate through the vertices in the one Ring and find the clost to the target point
                    //
                    bool flag = false;
                    foreach (Int32 v in dmesh.VtxVerticesItr(current))
                    {
                        Vector3d thisVtx  = dmesh.GetVertex(v);
                        double   thisDist = thisVtx.DistanceSquared(target);
                        if (thisDist < currentDist)
                        {
                            flag        = true;
                            current     = v;
                            vtx         = thisVtx;
                            currentDist = thisDist;
                        }
                    }
                    //
                    // if the current point as closest - then  have a local optima
                    //
                    if (!flag)
                    {
                        break;
                    }
                }
                //
                // we now have a local optima
                // to check for a global optima look to see if hit is contained by one of the triangles in the one ring
                //
                bool f2 = false;
                foreach (Int32 t in dmesh.VtxTrianglesItr(current))
                {
                    Index3i    tri      = dmesh.GetTriangle(t);
                    Triangle3d triangle = new Triangle3d(
                        dmesh.GetVertex(tri.a),
                        dmesh.GetVertex(tri.b),
                        dmesh.GetVertex(tri.c)
                        );
                    double[] xs = new double[3] {
                        triangle.V0.x, triangle.V1.x, triangle.V2.x
                    };
                    double[] ys = new double[3] {
                        triangle.V0.y, triangle.V1.y, triangle.V2.y
                    };
                    double[] zs = new double[3] {
                        triangle.V0.z, triangle.V1.z, triangle.V2.z
                    };

                    if (
                        target.x >= xs.Min() &&
                        target.x <= xs.Max() &&
                        target.y >= ys.Min() &&
                        target.y <= ys.Max() &&
                        target.z >= zs.Min() &&
                        target.z <= zs.Max()
                        )
                    {
                        f2            = true;
                        currentHitTri = tri;
                    }
                }
                //
                // if we found on triamgle that contain the current hit then we have finished
                //
                if (f2)
                {
                    break;
                }
            }
            if (count >= dmesh.VertexCount)
            {
                //
                // This is the unoptimized verion but it is guaranteed to find a solution if one exits
                //

                current = -1;
                float currentDist = float.MaxValue;
                if (currentHit != null)
                {
                    for (int i = 0; i < mesh.vertices.Length; i++)
                    {
                        Vector3 vtx  = mesh.vertices[i];
                        float   dist = (currentHit - vtx).sqrMagnitude;
                        if (dist < currentDist)
                        {
                            current     = i;
                            currentDist = dist;
                        }
                    }
                }
                //
                // Check that the closet vertex to the point is an actual solution
                //
                bool f2 = false;
                foreach (Int32 t in dmesh.VtxTrianglesItr(current))
                {
                    Index3i    tri      = dmesh.GetTriangle(t);
                    Triangle3d triangle = new Triangle3d(
                        dmesh.GetVertex(tri.a),
                        dmesh.GetVertex(tri.b),
                        dmesh.GetVertex(tri.c)
                        );
                    double[] xs = new double[3] {
                        triangle.V0.x, triangle.V1.x, triangle.V2.x
                    };
                    double[] ys = new double[3] {
                        triangle.V0.y, triangle.V1.y, triangle.V2.y
                    };
                    double[] zs = new double[3] {
                        triangle.V0.z, triangle.V1.z, triangle.V2.z
                    };

                    if (
                        target.x >= xs.Min() &&
                        target.x <= xs.Max() &&
                        target.y >= ys.Min() &&
                        target.y <= ys.Max() &&
                        target.z >= zs.Min() &&
                        target.z <= zs.Max()
                        )
                    {
                        f2            = true;
                        currentHitTri = tri;
                    }
                }
                //
                // if we found on triamgle that contain the current hit then we have finished
                //
                if (!f2)
                {
                    Debug.LogError(" Mesh Vertex Search : No Solution Found");
                    return;
                }
            }
            selectedVertex              = current;
            sphere                      = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            sphere.transform.position   = transform.TransformPoint(mesh.vertices[current]);
            sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
            sphere.transform.parent     = transform;
        }
    }