コード例 #1
0
 void _PickSector(SECTR_Portal myPortal)
 {
     HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
     if (Event.current.type == EventType.MouseMove)
     {
         _ComputeCursorVert();
     }
     else if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && !Event.current.alt && !Event.current.control)
     {
         SECTR_Sector sector = _GetSectorFromSelection();
         if (sector)
         {
             SECTR_Undo.Record(myPortal, "Assign Sector to Portal.");
             if (pickBack)
             {
                 myPortal.BackSector = sector;
             }
             else
             {
                 myPortal.FrontSector = sector;
             }
             EditorUtility.SetDirty(myPortal);
             pickFront = false;
             pickBack  = false;
             _EndSelection();
         }
     }
     else if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Escape)
     {
         pickBack  = false;
         pickFront = false;
         _EndSelection();
     }
 }
コード例 #2
0
    void _SwapSectors(SECTR_Portal myPortal)
    {
        SECTR_Undo.Record(myPortal, "Swap Portal Sectors");
        SECTR_Sector oldFront = myPortal.FrontSector;
        SECTR_Sector oldBack  = myPortal.BackSector;

        myPortal.FrontSector = null;
        myPortal.BackSector  = null;
        myPortal.FrontSector = oldBack;
        myPortal.BackSector  = oldFront;
        EditorUtility.SetDirty(myPortal);
    }
コード例 #3
0
    private bool _DrawChildControl(SECTR_LOD myLOD, SECTR_LOD.LODSet lodSet, Transform transform, bool hasChildren)
    {
        string undoString   = "Changed LOD";
        bool   expanded     = false;
        float  labelWidth   = Screen.width * 0.3f;
        float  checkWidth   = 30;
        float  buffer       = 5;
        Rect   propertyRect = EditorGUILayout.BeginHorizontal(GUILayout.Width(labelWidth));

        if (hasChildren)
        {
            hierarchyFoldouts.TryGetValue(transform, out expanded);
            hierarchyFoldouts[transform] = EditorGUILayout.Foldout(expanded, transform.name);
        }
        else
        {
            EditorGUILayout.LabelField(transform.name, GUILayout.Width(labelWidth));
        }
        EditorGUILayout.EndHorizontal();

        SECTR_LOD.LODEntry entry = lodSet.GetEntry(transform.gameObject);
        bool isChecked           = entry != null;
        bool newChecked          = GUI.Toggle(new Rect(propertyRect.xMax + buffer,
                                                       propertyRect.y,
                                                       checkWidth,
                                                       propertyRect.height),
                                              isChecked,
                                              GUIContent.none);

        if (newChecked != isChecked)
        {
            SECTR_Undo.Record(myLOD, undoString);
            if (newChecked)
            {
                entry = lodSet.Add(transform.gameObject, null);
            }
            else
            {
                lodSet.Remove(transform.gameObject);
                entry = null;
            }
            isChecked = newChecked;
            myLOD.Reset();
        }

        if (entry != null && transform.GetComponent <Renderer>())
        {
            Renderer newSource = (Renderer)EditorGUI.ObjectField(new Rect(propertyRect.xMax + checkWidth + buffer,
                                                                          propertyRect.y,
                                                                          Screen.width - (propertyRect.xMax + checkWidth + buffer * 2),
                                                                          propertyRect.height),
                                                                 GUIContent.none,
                                                                 entry.lightmapSource,
                                                                 typeof(Renderer),
                                                                 true);
            if (newSource != entry.lightmapSource)
            {
                SECTR_Undo.Record(myLOD, undoString);
                entry.lightmapSource = newSource;
                myLOD.Reset();
            }
        }
        return(expanded);
    }
コード例 #4
0
    void _CompleteHull(SECTR_Hull myHull)
    {
        int numNewVerts = newHullVerts.Count;

        if (numNewVerts >= 3)
        {
            Plane   hullPlane  = new Plane(newHullVerts[0], newHullVerts[1], newHullVerts[2]);
            Vector3 hullNormal = hullPlane.normal;

            // For new hulls, set their xform to match the hull geo.
            if (myHull.ForceEditHull && myHull.CenterOnEdit)
            {
                Vector3 newPos = Vector3.zero;
                for (int vertIndex = 0; vertIndex < numNewVerts; ++vertIndex)
                {
                    newPos += newHullVerts[vertIndex];
                }
                newPos /= newHullVerts.Count;
                myHull.transform.position = newPos;
                myHull.transform.forward  = hullNormal;
            }

            // Constructu a new mesh.
            Mesh newMesh = new Mesh();
            newMesh.name = myHull.name;
            Vector3[] newVerts   = new Vector3[numNewVerts];
            Vector3[] newNormals = new Vector3[numNewVerts];
            Vector2[] newUVs     = new Vector2[numNewVerts];

            // Compute new positions and normals, which are always in hull local space.
            Vector3 localNormal = myHull.transform.worldToLocalMatrix.MultiplyVector(hullNormal);
            Vector3 min         = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3 max         = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            for (int vertIndex = 0; vertIndex < numNewVerts; ++vertIndex)
            {
                Vector3 localPosition = myHull.transform.worldToLocalMatrix.MultiplyPoint3x4(newHullVerts[vertIndex]);
                newVerts[vertIndex]   = localPosition;
                newNormals[vertIndex] = localNormal;
                min = Vector3.Min(min, localPosition);
                max = Vector3.Max(max, localPosition);
            }
            // Compute a planar projection for the UVs.
            Vector3 uvScalar = new Vector3(1f / max.x - min.x, 1f / max.y - min.y, 1);
            for (int vertIndex = 0; vertIndex < numNewVerts; ++vertIndex)
            {
                newUVs[vertIndex] = Vector3.Scale(newVerts[vertIndex], uvScalar);
            }
            // Triangle indices assume a CW sorting of the verts.
            int   numTriangles = numNewVerts - 2;
            int[] triangles    = new int[numTriangles * 3];
            for (int triIndex = 0; triIndex < numTriangles; ++triIndex)
            {
                triangles[triIndex * 3]     = 0;
                triangles[triIndex * 3 + 1] = triIndex + 1;
                triangles[triIndex * 3 + 2] = triIndex + 2;
            }
            // Fill out the mesh stuffs.
            newMesh.vertices  = newVerts;
            newMesh.normals   = newNormals;
            newMesh.uv        = newUVs;
            newMesh.triangles = triangles;

            // Now create a new, unique mesh asset for the hull.
            // We use assets instead of storing geometry in the scene to ensure that everything serializes properly.
            string sceneDir     = null;
            string sceneName    = null;
            string exportDir    = SECTR_Asset.MakeExportFolder("Portals", false, out sceneDir, out sceneName);
            string newAssetName = exportDir + newMesh.name + ".asset";
            newAssetName = AssetDatabase.GenerateUniqueAssetPath(newAssetName);
            AssetDatabase.CreateAsset(newMesh, newAssetName);

            // Let the hull know that we've modified it in an undo friendly way.
            SECTR_Undo.Record(myHull, "Created Portal");
            myHull.HullMesh = newMesh;
        }
        _EndNewHull(myHull, false);
    }
コード例 #5
0
    public override void OnInspectorGUI()
    {
        SECTR_LOD myLOD           = (SECTR_LOD)target;
        float     lodButtonHeight = 50;
        float     lodGutterSize   = 4f;

        if (lodButtonStyle == null)
        {
            lodButtonStyle         = new GUIStyle(GUI.skin.button);
            lodButtonStyle.padding = new RectOffset();
            lodButtonStyle.margin  = new RectOffset();
        }

        if (Event.current.type == EventType.Repaint)
        {
            lodRects.Clear();
        }

        EditorGUILayout.BeginVertical();

        Rect lodListRect = EditorGUILayout.BeginVertical();

        GUI.enabled = false;
        GUILayout.Button(GUIContent.none, GUILayout.Height(lodButtonHeight));
        GUI.enabled = true;
        EditorGUILayout.EndVertical();

        float addButtonSize = lodListRect.width * 0.1f;
        int   numLODs       = myLOD.LODs.Count;
        float minThreshold  = 1;
        float insertPos     = lodListRect.xMin;

        for (int lodIndex = 0; lodIndex < numLODs; ++lodIndex)
        {
            SECTR_LOD.LODSet thisSet     = myLOD.LODs[lodIndex];
            float            buttonScale = 1f - thisSet.Threshold;
            float            percent     = 1f;
            if (lodIndex > 0)
            {
                float prevThreshold = myLOD.LODs[lodIndex - 1].Threshold;
                buttonScale -= 1f - prevThreshold;
                percent      = myLOD.LODs[lodIndex - 1].Threshold;
            }

            float buttonWidth = buttonScale * (lodListRect.width - addButtonSize);
            Rect  buttonRect  = new Rect(insertPos + lodGutterSize * 0.5f, lodListRect.y, buttonWidth - lodGutterSize, lodListRect.height);

            if (GUI.Button(buttonRect, "LOD" + lodIndex + "\n" + percent.ToString("P1"), lodButtonStyle))
            {
                selectedLOD = lodIndex;
            }
            if (Event.current.type == EventType.Repaint)
            {
                lodRects.Add(buttonRect);
            }
            insertPos += buttonWidth;

            minThreshold = Mathf.Min(minThreshold, thisSet.Threshold);
        }

        if (minThreshold > 0f && myLOD.LODs.Count > 0)
        {
            Rect culledRect = new Rect(insertPos + lodGutterSize * 0.5f, lodListRect.y, lodListRect.xMax - insertPos - addButtonSize - lodGutterSize, lodListRect.height);
            if (GUI.Button(culledRect, "Culled\n" + minThreshold.ToString("P1"), lodButtonStyle))
            {
                selectedLOD = -1;
            }

            if (Event.current.type == EventType.Repaint)
            {
                lodRects.Add(culledRect);
            }
        }

        GUI.enabled = minThreshold > 0;
        Rect addRect = myLOD.LODs.Count > 0 ? new Rect(lodListRect.xMax - addButtonSize, lodListRect.y, addButtonSize, lodListRect.height) :
                       new Rect(lodListRect.xMin, lodListRect.y, lodListRect.width, lodListRect.height);

        if (GUI.Button(addRect, myLOD.LODs.Count > 0 ? "+" : "+\n(Add LOD)", lodButtonStyle))
        {
            SECTR_Undo.Record(myLOD, "Added LOD");
            SECTR_LOD.LODSet newSet = new SECTR_LOD.LODSet();
            if (myLOD.LODs.Count == 0)
            {
                Transform[] children    = myLOD.GetComponentsInChildren <Transform>();
                int         numChildren = children.Length;
                for (int childIndex = 0; childIndex < numChildren; ++childIndex)
                {
                    if (children[childIndex] != myLOD.transform)
                    {
                        newSet.Add(children[childIndex].gameObject, null);
                    }
                }
            }
            else
            {
                SECTR_LOD.LODSet prevSet = myLOD.LODs[myLOD.LODs.Count - 1];
                int numEntries           = prevSet.LODEntries.Count;
                for (int entryIndex = 0; entryIndex < numEntries; ++entryIndex)
                {
                    SECTR_LOD.LODEntry prevEntry = prevSet.LODEntries[entryIndex];
                    newSet.Add(prevEntry.gameObject, prevEntry.lightmapSource);
                }
            }
            newSet.Threshold = minThreshold * 0.5f;
            selectedLOD      = myLOD.LODs.Count;
            myLOD.LODs.Add(newSet);
        }
        GUI.enabled = true;

        int lodToRemove = -1;

        if (selectedLOD >= 0 && selectedLOD < myLOD.LODs.Count)
        {
            float sliderMin = 0;
            float sliderMax = 1;

            if (selectedLOD < myLOD.LODs.Count - 1)
            {
                sliderMin = myLOD.LODs[selectedLOD + 1].Threshold;
            }
            if (selectedLOD > 0)
            {
                sliderMax = myLOD.LODs[selectedLOD - 1].Threshold;
            }

            myLOD.LODs[selectedLOD].Threshold = EditorGUILayout.Slider("LOD" + selectedLOD + " Threshold", myLOD.LODs[selectedLOD].Threshold, sliderMin, sliderMax);

            detailsFoldout = EditorGUILayout.Foldout(detailsFoldout, "LOD" + selectedLOD + " Members");
            if (detailsFoldout)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Name");
                GUILayout.Label("Included");
                GUILayout.Label("Lightmap Proxy");
                EditorGUILayout.EndHorizontal();
                _BuildChildControls(myLOD, myLOD.LODs[selectedLOD], myLOD.transform, true);
            }

            if (GUILayout.Button("Remove LOD" + selectedLOD))
            {
                if (EditorUtility.DisplayDialog("Confirm LOD Removal", "Are you sure you wish to remove LOD " + selectedLOD + "?", "Yes", "No"))
                {
                    lodToRemove = selectedLOD;
                }
            }
        }
        else if (selectedLOD == -1)
        {
            serializedObject.Update();
            DrawProperty("CullSiblings");
            serializedObject.ApplyModifiedProperties();
        }

        EditorGUILayout.EndVertical();

        if (lodToRemove >= 0)
        {
            SECTR_Undo.Record(myLOD, "Removed LOD");
            myLOD.LODs.RemoveAt(lodToRemove);
        }

        if (Event.current.type == EventType.Repaint)
        {
            lodListRectPerm = lodListRect;
        }

        int dragLod = -1;

        if (lodListRectPerm.Contains(Event.current.mousePosition))
        {
            for (int lodIndex = 0; lodIndex < lodRects.Count - 1; ++lodIndex)
            {
                if (Event.current.mousePosition.x > lodRects[lodIndex].xMax &&
                    Event.current.mousePosition.x < lodRects[lodIndex + 1].xMin)
                {
                    dragLod = lodIndex;
                    break;
                }
            }
        }

        if (dragLod >= 0 && Event.current.type == EventType.MouseDown)
        {
            dragging    = true;
            selectedLOD = dragLod;
        }
        else if (Event.current.type == EventType.MouseUp)
        {
            dragging = false;
        }

        if (dragging && lodListRectPerm.Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseDrag)
        {
            float newThreshold = 1f - ((Event.current.mousePosition.x - lodListRect.x) / lodListRect.width);
            newThreshold = Mathf.Clamp01(newThreshold);
            if (selectedLOD < myLOD.LODs.Count - 1)
            {
                newThreshold = Mathf.Max(newThreshold, myLOD.LODs[selectedLOD + 1].Threshold);
            }
            if (selectedLOD > 0)
            {
                newThreshold = Mathf.Min(newThreshold, myLOD.LODs[selectedLOD - 1].Threshold);
            }
            myLOD.LODs[selectedLOD].Threshold = newThreshold;
        }

        if (dragging || dragLod >= 0)
        {
            EditorGUIUtility.AddCursorRect(new Rect(Event.current.mousePosition.x - 16,
                                                    Event.current.mousePosition.y - 16, 32, 32),
                                           MouseCursor.ResizeHorizontal);
        }
    }