Exemplo n.º 1
0
        void UpdateSelection()
        {
            //0.1 ms
            float     fTimeSlice         = 1.0f / (10000.0f);
            int       iTimeSliceInTicks  = (int)(fTimeSlice * System.Diagnostics.Stopwatch.Frequency);
            Transform rCanvas            = App.ActiveCanvas.transform;
            int       iNumCanvasChildren = rCanvas.childCount;

            //reset selection if we've moved or adjusted our size
            float   fSelectionRadius         = GetSize();
            Vector3 vSelectionCenter         = transform.position;
            Vector3 vSelectionCenterMovement = vSelectionCenter - m_SelectionPositionPrev;
            float   fSelectionRadiusDiff     = m_SelectionRadiusPrev - fSelectionRadius;

            if (vSelectionCenterMovement.sqrMagnitude > 0.0001f || Mathf.Abs(fSelectionRadiusDiff) > 0.001f)
            {
                ResetSelection();
                m_SelectionPositionPrev = vSelectionCenter;
                m_SelectionRadiusPrev   = fSelectionRadius;
            }
            m_SelectionInfoQueryWasComplete = m_SelectionInfoQueryComplete;
            float fObjectProgressPercent = 0.0f;

            //DebugDrawBounds();

            //early out if there's nothing to look at
            if (iNumCanvasChildren > 0 && m_SelectionObjectIndex < iNumCanvasChildren)
            {
                m_SelectionStopwatch.Reset();
                m_SelectionStopwatch.Start();
                bool bDone         = false;
                bool bComplexModel = false;

                //spin until we've taken up too much time
                while (!bDone)
                {
                    //check child bounds
                    Transform rChild = rCanvas.GetChild(m_SelectionObjectIndex);
                    if (rChild.gameObject.activeSelf)
                    {
                        bComplexModel = false;
                        MeshFilter rMeshFilter = rChild.GetComponent <MeshFilter>();
                        if (rMeshFilter == null)
                        {
                            //look for a complex model
                            ObjModelScript rModelScript = rChild.GetComponent <ObjModelScript>();
                            if (rModelScript)
                            {
                                if (m_SelectionObjectChildIndex < rModelScript.m_MeshChildren.Length)
                                {
                                    rMeshFilter   = rModelScript.m_MeshChildren[m_SelectionObjectChildIndex];
                                    bComplexModel = true;
                                }
                            }
                        }

                        if (rMeshFilter)
                        {
                            Bounds rMeshBounds = rMeshFilter.mesh.bounds;
                            rMeshBounds.Expand(fSelectionRadius);
                            Vector3 vTransformedCenter = rChild.InverseTransformPoint(vSelectionCenter);

                            if (rMeshBounds.Contains(vTransformedCenter))
                            {
                                //bounds valid, check vert intersection with sphere
                                int       iMeshVertCount = rMeshFilter.mesh.vertexCount;
                                Vector3[] aVerts         = rMeshFilter.mesh.vertices;
                                Vector3[] aNorms         = rMeshFilter.mesh.normals;
                                while (m_SelectionVertIndex < iMeshVertCount - 2)
                                {
                                    //check to see if we're within the sphere radius to the plane of this triangle
                                    Vector3 vVert        = aVerts[m_SelectionVertIndex];
                                    Vector3 vNorm        = aNorms[m_SelectionVertIndex];
                                    float   fDistToPlane = SignedDistancePlanePoint(ref vNorm, ref vVert, ref vTransformedCenter);
                                    if (Mathf.Abs(fDistToPlane) < fSelectionRadius)
                                    {
                                        //we're within the radius to this triangle's plane, find the projected point
                                        fDistToPlane *= -1.0f;
                                        Vector3 vPlaneOffsetVector = vNorm * fDistToPlane;
                                        Vector3 vPlaneIntersection = vTransformedCenter + vPlaneOffsetVector;

                                        Vector3 vVert2 = aVerts[m_SelectionVertIndex + 1];
                                        Vector3 vVert3 = aVerts[m_SelectionVertIndex + 2];

                                        //walk the projected point toward the triangle center
                                        Vector3 vTriCenter    = (vVert + vVert2 + vVert3) * 0.33333f;
                                        Vector3 vToTriCenter  = vTriCenter - vPlaneIntersection;
                                        float   fWalkDistance = Mathf.Min(vToTriCenter.magnitude, fSelectionRadius);
                                        vToTriCenter.Normalize();
                                        vToTriCenter       *= fWalkDistance;
                                        vPlaneIntersection += vToTriCenter;

                                        //see if this projected point is in the triangle
                                        if (PointInTriangle(ref vPlaneIntersection, ref vVert, ref vVert2, ref vVert3))
                                        {
                                            //selected!
                                            SelectionObject rNewSelectedObject = new SelectionObject();
                                            rNewSelectedObject.m_Object        = rChild.gameObject;
                                            rNewSelectedObject.m_ComplexObject = bComplexModel;
                                            m_CurrentSelection.Add(rNewSelectedObject);

                                            //this will guarantee we'll move on from this model, complex or not
                                            bComplexModel = false;
                                            break;
                                        }
                                    }

                                    //after each triangle, check our time
                                    m_SelectionVertIndex += 3;
                                    bDone = m_SelectionStopwatch.ElapsedTicks > iTimeSliceInTicks;
                                    if (bDone)
                                    {
                                        fObjectProgressPercent = (float)m_SelectionVertIndex / (float)iMeshVertCount;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    //if we're not flagged as done, we just finished this object, so move on to the next
                    if (!bDone)
                    {
                        //if we're looking at a complex model, look at the next piece of the model
                        if (bComplexModel)
                        {
                            ++m_SelectionObjectChildIndex;
                        }
                        else
                        {
                            //move to the next object
                            ++m_SelectionObjectIndex;
                            m_SelectionObjectChildIndex = 0;
                        }

                        m_SelectionVertIndex = 0;
                        if (m_SelectionObjectIndex >= iNumCanvasChildren)
                        {
                            //if we reached the end of the line, we're done
                            break;
                        }

                        //might as well check per object
                        bDone = m_SelectionStopwatch.ElapsedTicks > iTimeSliceInTicks;
                    }
                }

                m_SelectionStopwatch.Stop();
            }

            //set progress
            float fProgressInterval = 1.0f;

            if (iNumCanvasChildren > 0)
            {
                fProgressInterval /= (float)iNumCanvasChildren;
            }
            float fCanvasProgress = fProgressInterval * (float)m_SelectionObjectIndex;
            float fBrushProgress  = fObjectProgressPercent * fProgressInterval;

            SetToolProgress(fCanvasProgress + fBrushProgress + 0.001f);
        }
Exemplo n.º 2
0
        void LoadModel()
        {
            // Clean up existing model
            if (m_ModelInstance != null)
            {
                GameObject.Destroy(m_ModelInstance.gameObject);
            }

            // Early out if we don't have a model to clone.
            // This can happen if model loading is deferred.
            if (m_Model == null || m_Model.m_ModelParent == null)
            {
                return;
            }

            m_ModelInstance = Instantiate(m_Model.m_ModelParent);
            m_ModelInstance.gameObject.SetActive(true);
            m_ModelInstance.parent = this.transform;

            Coords.AsLocal[m_ModelInstance] = TrTransform.identity;
            float maxExtent = 2 * Mathf.Max(m_Model.m_MeshBounds.extents.x,
                                            Mathf.Max(m_Model.m_MeshBounds.extents.y, m_Model.m_MeshBounds.extents.z));
            float size;

            if (maxExtent == 0.0f)
            {
                // If we created a widget with a model that doesn't have geo, we won't have calculated a
                // bounds worth much.  In that case, give us a default size.
                size = 1.0f;
            }
            else
            {
                size = kInitialSizeMeters_RS * App.METERS_TO_UNITS / maxExtent;
            }

            m_InitSize_CS = size / Coords.CanvasPose.scale;

            // Models are created in the main canvas.  Cache model layer in case it's overridden later.
            HierarchyUtils.RecursivelySetLayer(transform, App.Scene.MainCanvas.gameObject.layer);
            m_BackupLayer = m_ModelInstance.gameObject.layer;

            // Set a new batchId on this model so it can be picked up in GPU intersections.
            m_BatchId = GpuIntersector.GetNextBatchId();
            HierarchyUtils.RecursivelySetMaterialBatchID(m_ModelInstance, m_BatchId);
            WidgetManager.m_Instance.AddWidgetToBatchMap(this, m_BatchId);

            Vector3 ratios = GetBoundsRatios(m_Model.m_MeshBounds);

            m_ContainerBloat.x = Mathf.Max(0, m_MinContainerRatio - ratios.x);
            m_ContainerBloat.y = Mathf.Max(0, m_MinContainerRatio - ratios.y);
            m_ContainerBloat.z = Mathf.Max(0, m_MinContainerRatio - ratios.z);
            m_ContainerBloat  /= m_MinContainerRatio;               // Normalize for the min ratio.
            m_ContainerBloat  *= m_MaxBloat / App.Scene.Pose.scale; // Apply bloat to appropriate axes.

            m_BoxCollider.size = m_Model.m_MeshBounds.size + m_ContainerBloat;
            m_BoxCollider.transform.localPosition = m_Model.m_MeshBounds.center;

            InitSnapGhost(m_Model.m_ModelParent, m_ModelInstance);

            // Remove previous model vertex recording.
            WidgetManager.m_Instance.AdjustModelVertCount(-m_NumVertsTrackedByWidgetManager);
            m_NumVertsTrackedByWidgetManager = 0;

            m_ObjModelScript = GetComponentInChildren <ObjModelScript>();
            m_ObjModelScript.Init();
            if (m_ObjModelScript.NumMeshes == 0)
            {
                OutputWindowScript.Error("No usable geometry in model");
            }
            else
            {
                m_NumVertsTrackedByWidgetManager = m_ObjModelScript.GetNumVertsInMeshes();
                WidgetManager.m_Instance.AdjustModelVertCount(m_NumVertsTrackedByWidgetManager);
            }

            if (m_Model.IsCached())
            {
                m_Model.RefreshCache();
            }
        }