Beispiel #1
0
        void GetInfoFromSelection()
        {
            //don't start looking for a color until we're done with our selection
            Transform rCanvas = App.ActiveCanvas.transform;

            if (!m_SelectionInfoQueryComplete && (m_SelectionObjectIndex >= rCanvas.childCount))
            {
                int     iBestObject      = -1;
                float   fBestDistance    = 999999.0f;
                Vector3 vSelectionCenter = transform.position;
                float   fSelectionRadius = GetSize();
                for (int i = 0; i < m_CurrentSelection.Count; ++i)
                {
                    //don't try to get info from complex objects
                    SelectionObject rSelectedObject = m_CurrentSelection[i];
                    if (rSelectedObject.m_ComplexObject)
                    {
                        continue;
                    }

                    MeshFilter rMeshFilter        = rSelectedObject.m_Object.GetComponent <MeshFilter>();
                    Vector3    vTransformedCenter = rSelectedObject.m_Object.transform.InverseTransformPoint(vSelectionCenter);

                    //check each triangle for intersection
                    int       iMeshVertCount = rMeshFilter.mesh.vertexCount;
                    Vector3[] aVerts         = rMeshFilter.mesh.vertices;
                    Vector3[] aNorms         = rMeshFilter.mesh.normals;
                    for (int j = 0; j < iMeshVertCount; j += 3)
                    {
                        //check to see if we're within the sphere radius to the plane of this triangle
                        Vector3 vVert           = aVerts[j];
                        Vector3 vNorm           = aNorms[j];
                        float   fDistToPlane    = SignedDistancePlanePoint(ref vNorm, ref vVert, ref vTransformedCenter);
                        float   fAbsDistToPlane = Mathf.Abs(fDistToPlane);
                        if (fAbsDistToPlane < fSelectionRadius && fAbsDistToPlane < fBestDistance)
                        {
                            //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[i + 1];
                            Vector3 vVert3 = aVerts[i + 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))
                            {
                                //our projected point is in this triangle, store this distance as the best
                                iBestObject   = i;
                                fBestDistance = fDistToPlane;
                                break;
                            }
                        }
                    }
                }

                //this can happen if we don't have a selection
                if (iBestObject != -1)
                {
                    BaseBrushScript rBrushScript = m_CurrentSelection[iBestObject].m_Object.GetComponent <BaseBrushScript>();
                    if (rBrushScript)
                    {
                        m_SelectionColor     = rBrushScript.CurrentColor;
                        m_SelectionBrush     = rBrushScript.Descriptor;
                        m_SelectionInfoValid = true;
                    }
                }
                else
                {
                    m_SelectionColor = Color.white;
                    m_SelectionBrush = null;
                }

                m_SelectionInfoQueryComplete = true;
            }
        }
Beispiel #2
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);
        }