Ejemplo n.º 1
0
        /**
         * Center the mesh pivot at the average of passed indices.
         */
        public static void CenterPivot(this pb_Object pb, int[] indices)
        {
            Vector3[] verts = pb.VerticesInWorldSpace(indices == null ? pb.uniqueIndices : indices);

            Vector3 center = Vector3.zero;

            foreach (Vector3 v in verts)
            {
                center += v;
            }

            center /= (float)verts.Length;

            // if(pbUtil.SharedSnapEnabled)
            //  center = pbUtil.SnapValue(center, pbUtil.SharedSnapValue);

            Vector3 dir = (pb.transform.position - center);

            pb.transform.position = center;

            // the last bool param force disables snapping vertices
            pb.TranslateVertices(pb.uniqueIndices, dir, true);

            pb.Refresh();
        }
Ejemplo n.º 2
0
        void RefreshSelectedFacePreview()
        {
            // Copy the currently selected vertices in world space.
            // World space so that we don't have to apply transforms
            // to match the current selection.
            Vector3[] verts = currentSelection.pb.VerticesInWorldSpace(currentSelection.face.indices);

            // face.indices == triangles, so wind the face to match
            int[] indices = new int[verts.Length];
            for (int i = 0; i < indices.Length; i++)
            {
                indices[i] = i;
            }

            // Now go through and move the verts we just grabbed out about .1m from the original face.
            Vector3 normal = pb_Math.Normal(verts);

            for (int i = 0; i < verts.Length; i++)
            {
                verts[i] += normal.normalized * .01f;
            }

            if (preview)
            {
                Destroy(preview.gameObject);
            }

            preview = pb_Object.CreateInstanceWithVerticesFaces(verts, new pb_Face[] { new pb_Face(indices) });
            preview.SetFaceMaterial(preview.faces, previewMaterial);
            preview.ToMesh();
            preview.Refresh();
        }
Ejemplo n.º 3
0
		void Start()
		{
			// Create a new ProBuilder cube to work with.
			pb = pb_ShapeGenerator.CubeGenerator(Vector3.one);

			// Cycle through each unique vertex in the cube (8 total), and assign a color
			// to the index in the sharedIndices array.
			int si_len = pb.sharedIndices.Length;
			Color[] vertexColors = new Color[si_len];
			for(int i = 0; i < si_len; i++)
			{
				vertexColors[i] = HSVtoRGB( (i/(float)si_len) * 360f, 1f, 1f);
			}

			// Now go through each face (vertex colors are stored the pb_Face class) and
			// assign the pre-calculated index color to each index in the triangles array.
			Color[] colors = pb.colors;

			for(int CurSharedIndex = 0; CurSharedIndex < pb.sharedIndices.Length; CurSharedIndex++)
			{
				foreach(int CurIndex in pb.sharedIndices[CurSharedIndex].array)
				{
					colors[CurIndex] = vertexColors[CurSharedIndex];
				}
			}

			pb.SetColors(colors);

			// In order for these changes to take effect, you must refresh the mesh
			// object.
			pb.Refresh();
		}
Ejemplo n.º 4
0
        /**
         *	\brief Rebuild targets if they can't be refreshed.
         */
        private static void StripAndProBuilderize(pb_Object[] targets, bool interactive = true)
        {
            for (int i = 0; i < targets.Length; i++)
            {
                if (interactive)
                {
                    EditorUtility.DisplayProgressBar(
                        "Refreshing ProBuilder Objects",
                        "Reshaping pb_Object " + targets[i].id + ".",
                        ((float)i / targets.Length));
                }

                pb_Object pb = targets[i];

                try
                {
                    pb.ToMesh();
                    pb.Refresh();
                    pb.Optimize();
                }
                catch
                {
                    if (pb.msh != null)
                    {
                        RebuildProBuilderMesh(pb);
                    }
                }
            }

            if (interactive)
            {
                EditorUtility.ClearProgressBar();
                EditorUtility.DisplayDialog("Rebuild ProBuilder Objects", "Successfully rebuilt " + targets.Length + " ProBuilder Objects", "Okay");
            }
        }
        private static void DoUpgrade(pb_Object[] all)
        {
            bool interactive = all != null && all.Length > 8;

            for (int i = 0; i < all.Length; i++)
            {
                pb_Object pb = all[i];

                if (interactive)
                {
                    EditorUtility.DisplayProgressBar(
                        "Applying Materials",
                        "Setting pb_Object " + all[i].id + ".",
                        ((float)i / all.Length));
                }

                pb.SetFaceMaterial(pb.faces, pb.gameObject.GetComponent <MeshRenderer>().sharedMaterial);

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            if (interactive)
            {
                EditorUtility.ClearProgressBar();
            }
        }
Ejemplo n.º 6
0
        private void RefreshSelectedFacePreview()
        {
            Vector3[] array  = currentSelection.pb.VerticesInWorldSpace(currentSelection.face.indices);
            int[]     array2 = new int[array.Length];
            for (int i = 0; i < array2.Length; i++)
            {
                array2[i] = i;
            }
            Vector3 vector = pb_Math.Normal(array);

            for (int j = 0; j < array.Length; j++)
            {
                array[j] += vector.normalized * 0.01f;
            }
            if ((bool)preview)
            {
                Object.Destroy(preview.gameObject);
            }
            preview = pb_Object.CreateInstanceWithVerticesFaces(array, new pb_Face[1]
            {
                new pb_Face(array2)
            });
            preview.SetFaceMaterial(preview.faces, previewMaterial);
            preview.ToMesh();
            preview.Refresh();
        }
Ejemplo n.º 7
0
    void Start()
    {
        // Create a new ProBuilder cube to work with.
        pb = pb_Shape_Generator.CubeGenerator(Vector3.one);

        // Cycle through each unique vertex in the cube (8 total), and assign a color
        // to the index in the sharedIndices array.
        int si_len = pb.sharedIndices.Length;

        Color[] vertexColors = new Color[si_len];
        for (int i = 0; i < si_len; i++)
        {
            vertexColors[i] = HSVtoRGB((i / (float)si_len) * 360f, 1f, 1f);
        }

        // Now go through each face (vertex colors are stored the pb_Face class) and
        // assign the pre-calculated index color to each index in the triangles array.
        Color[] colors = pb.colors;

        for (int CurSharedIndex = 0; CurSharedIndex < pb.sharedIndices.Length; CurSharedIndex++)
        {
            foreach (int CurIndex in pb.sharedIndices[CurSharedIndex].array)
            {
                colors[CurIndex] = vertexColors[CurSharedIndex];
            }
        }

        pb.SetColors(colors);

        // In order for these changes to take effect, you must refresh the mesh
        // object.
        pb.Refresh();
    }
Ejemplo n.º 8
0
    public void ChangeBackgroundColor(Color newColor)
    {
        Color color = newColor;

        // Cycle through each unique vertex in the cube (8 total), and assign a color to the index in the sharedIndices array.
        int si_len = backgroundPlane.sharedIndices.Length;

        Color[] vertexColors = new Color[si_len];

        for (int i = 0; i < si_len; i++)
        {
            vertexColors[i] = color;
        }

        // Now go through each face (vertex colors are stored the pb_Face class) and assign the pre-calculated index color to each index in the triangles array.
        Color[] colors = backgroundPlane.colors;

        for (int CurSharedIndex = 0; CurSharedIndex < backgroundPlane.sharedIndices.Length; CurSharedIndex++)
        {
            foreach (int CurIndex in backgroundPlane.sharedIndices[CurSharedIndex].array)
            {
                colors[CurIndex] = vertexColors[CurSharedIndex];
            }
        }

        backgroundPlane.SetColors(colors);

        // In order for these changes to take effect, you must refresh the mesh object.
        backgroundPlane.Refresh();
    }
Ejemplo n.º 9
0
        void RefreshSelectedFacePreview()
        {
            pb_Face face = new pb_Face(currentSelection.face);                  // Copy the currently selected face

            face.ShiftIndicesToZero();                                          // Shift the selected face indices to zero

            // Copy the currently selected vertices in world space.
            // World space so that we don't have to apply transforms
            // to match the current selection.
            Vector3[] verts = currentSelection.pb.VerticesInWorldSpace(currentSelection.face.distinctIndices);

            // Now go through and move the verts we just grabbed out about .1m from the original face.
            Vector3 normal = pb_Math.Normal(verts);

            for (int i = 0; i < verts.Length; i++)
            {
                verts[i] += normal.normalized * .01f;
            }

            if (preview)
            {
                Destroy(preview.gameObject);
            }

            preview = pb_Object.CreateInstanceWithVerticesFaces(verts, new pb_Face[1] {
                face
            });
            preview.SetFaceMaterial(preview.faces, previewMaterial);
            preview.ToMesh();
            preview.Refresh();
        }
Ejemplo n.º 10
0
        /**
         *  \brief Rebuild targets if they can't be refreshed.
         */
        private static void RebuildSharedIndices(pb_Object[] targets, bool interactive = true)
        {
            for (int i = 0; i < targets.Length; i++)
            {
                if (interactive)
                {
                    EditorUtility.DisplayProgressBar(
                        "Refreshing ProBuilder Objects",
                        "Reshaping pb_Object " + targets[i].id + ".",
                        ((float)i / targets.Length));
                }

                pb_Object pb = targets[i];

                try
                {
                    pb.SetSharedIndices(pb_IntArrayUtility.ExtractSharedIndices(pb.vertices));

                    pb.ToMesh();
                    pb.Refresh();
                    pb.Optimize();
                }
                catch (System.Exception e)
                {
                    Debug.LogError("Failed rebuilding " + pb.name + " shared indices cache.\n" + e.ToString());
                }
            }

            if (interactive)
            {
                EditorUtility.ClearProgressBar();
                EditorUtility.DisplayDialog("Rebuild Shared Index Cache", "Successfully rebuilt " + targets.Length + " shared index caches", "Okay");
            }
        }
Ejemplo n.º 11
0
        private static void RebuildProBuilderMesh(pb_Object pb)
        {
            try
            {
                GameObject go = pb.gameObject;
                pb.dontDestroyMeshOnDelete = true;
                Undo.DestroyObjectImmediate(pb);

                // don't delete pb_Entity here because it won't
                // actually get removed till the next frame, and
                // probuilderize wants to add it if it's missing
                // (which it looks like it is from c# side but
                // is not)

                pb = Undo.AddComponent <pb_Object>(go);
                pbMeshOps.ResetPbObjectWithMeshFilter(pb, true);

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }
            catch (System.Exception e)
            {
                Debug.LogError("Failed rebuilding ProBuilder mesh: " + e.ToString());
            }
        }
Ejemplo n.º 12
0
	void Start()
	{
		// Create a new ProBuilder cube to work with.
		pb = ProBuilder.CreatePrimitive(Shape.Cube);
	
		// Because of the way colors are stored (one color per-index in triangle array),
		// we have to keep track of what color belongs to what index.  A real pain, I am
		// aware.  This will be changed in the future - because it is a terrible method.
		Dictionary<int, Color32> vertexColors = new Dictionary<int, Color32>();

		// Cycle through each unique vertex in the cube (8 total), and assign a color
		// to the index in the sharedIndices array.
		int si_len = pb.sharedIndices.Length;
		for(int i = 0; i < si_len; i++)
		{
			vertexColors.Add(i, HSVtoRGB( (i/(float)si_len) * 360f, 1f, 1f) );
		}

		// Now go through each face (vertex colors are stored the pb_Face class) and
		// assign the pre-calculated index color to each index in the triangles array.
		foreach(pb_Face face in pb.faces)
		{
			Color32[] faceColors = new Color32[face.indices.Length];
			for(int i = 0; i < face.indices.Length; i++)
			{
				int index = pb.sharedIndices.IndexOf(face.indices[i]);
				faceColors[i] = vertexColors[index];
			}
			face.SetColors(faceColors);
		}

		// In order for these changes to take effect, you must refresh the mesh
		// object.
		pb.Refresh();
	}
Ejemplo n.º 13
0
        /**
         * Center the mesh pivot at the average of passed indices.
         */
        public static void CenterPivot(this pb_Object pb, int[] indices)
        {
            Vector3 center = Vector3.zero;

            if (indices != null)
            {
                Vector3[] verts = pb.VerticesInWorldSpace(indices);

                foreach (Vector3 v in verts)
                {
                    center += v;
                }

                center /= (float)verts.Length;
            }
            else
            {
                center = pb.transform.TransformPoint(pb.msh.bounds.center);
            }

            Vector3 dir = (pb.transform.position - center);

            pb.transform.position = center;

            pb.TranslateVertices_World(pb.msh.triangles, dir);

            pb.ToMesh();
            pb.Refresh();
        }
Ejemplo n.º 14
0
    /**
     *	\brief Duplicates and mirrors the passed pb_Object.
     *	@param pb The donor pb_Object.
     *	@param axe The axis to mirror the object on.
     *	\returns The newly duplicated pb_Object.
     *	\sa ProBuilder.Axis
     */
    public static pb_Object Mirror(pb_Object pb, Vector3 scale)
    {
        pb_Object p = ProBuilder.CreateObjectWithObject(pb);

        p.MakeUnique();

        p.transform.parent = pb.transform.parent;

        p.transform.position      = pb.transform.position;
        p.transform.localRotation = pb.transform.localRotation;

        Vector3 lScale = p.gameObject.transform.localScale;

        p.transform.localScale = new Vector3(lScale.x * scale.x, lScale.y * scale.y, lScale.z * scale.z);

        // if flipping on an odd number of axes, flip winding order
        if ((scale.x * scale.y * scale.z) < 0)
        {
            p.ReverseWindingOrder(p.faces);
        }

        p.FreezeScaleTransform();

        p.Refresh();
        p.GenerateUV2(true);

        pb_Editor_Utility.InitObjectFlags(p, ColliderType.MeshCollider, pb.entity.entityType);
        return(p);
    }
Ejemplo n.º 15
0
        /**
         * \brief Flips the winding order for the entire mesh.
         */
        // public static void ReverseWindingOrder(this pb_Object pb)
        // {
        //  for(int i = 0; i < pb.faces.Length; i++)
        //      pb.faces[i].ReverseIndices();

        //  pb.ToMesh();
        //  pb.Refresh();
        // }

        /**
         *	\brief Reverse the winding order for each passed #pb_Face.
         *	@param faces The faces to apply normal flippin' to.
         *	\returns Nothing.  No soup for you.
         *	\sa SelectedFaces pb_Face
         */
        public static void ReverseWindingOrder(this pb_Object pb, pb_Face[] faces)
        {
            for (int i = 0; i < faces.Length; i++)
            {
                faces[i].ReverseIndices();
            }

            pb.ToMesh();
            pb.Refresh();
        }
Ejemplo n.º 16
0
        /**
         * Move the object pivot to @worldPosition.
         */
        public static void CenterPivot(this pb_Object pb, Vector3 worldPosition)
        {
            Vector3 offset = pb.transform.position - worldPosition;

            pb.transform.position = worldPosition;

            pb.TranslateVertices_World(pb.msh.triangles, offset);

            pb.ToMesh();
            pb.Refresh();
        }
Ejemplo n.º 17
0
        /**
         * Called when a property on a pb_Object is changed by another user. Rebuilds the ProBuilder mesh.
         *
         * @param   SerializedProperty property that changed.
         */
        private static void OnPropertyChange(SerializedProperty property)
        {
            // Rebuild the mesh if we haven't already this frame.
            pb_Object obj = property.serializedObject.targetObject as pb_Object;

            if (obj != null && m_rebuiltObjects.Add(obj))
            {
                obj.ToMesh();
                obj.Refresh();
            }
        }
        void Update()
        {
            float time = Time.time * speed;

            Vector3 position = new Vector3(
                Mathf.PerlinNoise(time, time) * travel,
                2,
                Mathf.PerlinNoise(time + 1f, time + 1f) * travel
                );

            transform.position = position;

            if (target == null)
            {
                Debug.LogWarning("Missing the ProBuilder Mesh target!");
                return;
            }

            // instead of testing distance by converting each face's center to world space,
            // convert the world space of this object to the pb-Object local transform.
            Vector3 pbRelativePosition = target.transform.InverseTransformPoint(transform.position);

            // reset the last colored face to white
            if (nearest != null)
            {
                target.SetFaceColor(nearest, Color.white);
            }

            // iterate each face in the pb_Object looking for the one nearest
            // to this object.
            int   faceCount        = target.faces.Length;
            float smallestDistance = Mathf.Infinity;

            nearest = target.faces[0];

            for (int i = 0; i < faceCount; i++)
            {
                float distance = Vector3.Distance(pbRelativePosition, FaceCenter(target, target.faces[i]));

                if (distance < smallestDistance)
                {
                    smallestDistance = distance;
                    nearest          = target.faces[i];
                }
            }

            // Set a single face's vertex colors.  If you're updating more than one face, consider using
            // the pb_Object.SetColors(Color[] colors); function instead.
            target.SetFaceColor(nearest, Color.blue);

            // Apply the stored vertex color array to the Unity mesh.
            target.Refresh(RefreshMask.Colors);
        }
Ejemplo n.º 19
0
    private void Start()
    {
        target = pb_ShapeGenerator.PlaneGenerator(travel, travel, 25, 25, Axis.Up, smooth: false);
        target.SetFaceMaterial(target.faces, pb_Constant.DefaultMaterial);
        target.transform.position = new Vector3(travel * 0.5f, 0f, travel * 0.5f);
        target.ToMesh();
        target.Refresh();
        Camera main = Camera.main;

        main.transform.position      = new Vector3(25f, 40f, 0f);
        main.transform.localRotation = Quaternion.Euler(new Vector3(65f, 0f, 0f));
    }
Ejemplo n.º 20
0
        /**
         *	\brief Scale vertices and set transform.localScale to Vector3.one.
         */
        public static void FreezeScaleTransform(this pb_Object pb)
        {
            Vector3[] v = pb.vertices;
            for (int i = 0; i < v.Length; i++)
            {
                v[i] = Vector3.Scale(v[i], pb.transform.localScale);
            }

            pb.SetVertices(v);
            pb.ToMesh();
            pb.transform.localScale = new Vector3(1f, 1f, 1f);
            pb.Refresh();
        }
Ejemplo n.º 21
0
        /**
         *	\brief Duplicates and mirrors the passed pb_Object.
         *	@param pb The donor pb_Object.
         *	@param axe The axis to mirror the object on.
         *	\returns The newly duplicated pb_Object.
         *	\sa ProBuilder.Axis
         */
        public static pb_Object Mirror(pb_Object pb, Vector3 scale)
        {
            pb_Object p = pb_Object.InitWithObject(pb);

            p.MakeUnique();

            p.transform.parent = pb.transform.parent;

            p.transform.localRotation = pb.transform.localRotation;

            Vector3 lScale = p.gameObject.transform.localScale;

            p.transform.localScale = new Vector3(lScale.x * scale.x, lScale.y * scale.y, lScale.z * scale.z);

            // if flipping on an odd number of axes, flip winding order
            if ((scale.x * scale.y * scale.z) < 0)
            {
                p.ReverseWindingOrder(p.faces);
            }

            p.FreezeScaleTransform();

            p.transform.localScale = pb.transform.localScale;

            Collider     col     = pb.GetComponent <Collider>();
            ColliderType colType = ColliderType.None;

            if (col != null)
            {
                if (col is MeshCollider)
                {
                    colType = ColliderType.MeshCollider;
                }
                else
                {
                    colType = ColliderType.BoxCollider;
                }
            }

            pb_Editor_Utility.InitObjectFlags(p, colType, pb.GetComponent <pb_Entity>().entityType);

            p.ToMesh();
            p.Refresh();

            // InitObjectFlags runs ScreenCenter()
            p.transform.position = pb.transform.position;

            Undo.RegisterCreatedObjectUndo(p.gameObject, "Mirror Object");

            return(p);
        }
Ejemplo n.º 22
0
        /**
         *  Do the thing.  Return a pb_ActionResult indicating the success/failure of action.
         */
        public override pb_ActionResult DoAction()
        {
            #if !UNITY_4_6 && !UNITY_4_7
            ShadowCastingMode shadowMode = (ShadowCastingMode)pb_PreferencesInternal.GetInt("pb_CreateShadowObject_shadowMode", (int)ShadowCastingMode.ShadowsOnly);
            #endif
            float         extrudeDistance = pb_PreferencesInternal.GetFloat("pb_CreateShadowObject_volumeSize", .08f);
            ExtrudeMethod extrudeMethod   = (ExtrudeMethod)pb_PreferencesInternal.GetInt("pb_CreateShadowObject_extrudeMethod", (int)ExtrudeMethod.FaceNormal);

            foreach (pb_Object pb in selection)
            {
                pb_Object shadow = GetShadowObject(pb);

                if (shadow == null)
                {
                    continue;
                }

                foreach (pb_Face f in shadow.faces)
                {
                    f.ReverseIndices(); f.manualUV = true;
                }
                shadow.Extrude(shadow.faces, extrudeMethod, extrudeDistance);
                shadow.ToMesh();
                shadow.Refresh();
                shadow.Optimize();

                #if !UNITY_4_6 && !UNITY_4_7
                MeshRenderer mr = shadow.gameObject.GetComponent <MeshRenderer>();
                mr.shadowCastingMode = shadowMode;
                if (shadowMode == ShadowCastingMode.ShadowsOnly)
                {
                    mr.receiveShadows = false;
                }
                #endif

                Collider collider = shadow.GetComponent <Collider>();

                while (collider != null)
                {
                    GameObject.DestroyImmediate(collider);
                    collider = shadow.GetComponent <Collider>();
                }
            }

            // This is necessary!  Otherwise the pb_Editor will be working with caches from
            // outdated meshes and throw errors.
            pb_Editor.Refresh();

            return(new pb_ActionResult(Status.Success, "Create Shadow Object"));
        }
Ejemplo n.º 23
0
    void Update()
    {
        if (Input.GetMouseButtonUp(0) && FaceRaycast(Input.mousePosition, out selectedObject, out selectedFace))
        {
            // Materials are set per-face, and pb_Object handles merging alike faces to a single submesh.
            selectedFace.material = materials[(m_MaterialIndex++) % materials.Length];

            // Rebuild the mesh submeshes and vertices
            selectedObject.ToMesh();

            // Rebuildd UVs, normals, tangents, collisions.
            selectedObject.Refresh();
        }
    }
Ejemplo n.º 24
0
        private static void SetCollider(GameObject target)
        {
            pb_Object pb = target.GetComponent <pb_Object>();

                        #if !PROTOTYPE
            pb.SetFaceMaterial(pb.faces, pb_Constant.ColliderMaterial);
                        #else
            target.GetComponent <MeshRenderer>().sharedMaterial = pb_Constant.ColliderMaterial;
                        #endif

            pb.ToMesh();
            pb.Refresh();

            SetEditorFlags((StaticEditorFlags)(StaticEditorFlags.NavigationStatic | StaticEditorFlags.OffMeshLinkGeneration), target);
        }
Ejemplo n.º 25
0
        private static void OnFaceChanged(pb_Object pb)
        {
            pb.ToMesh();
            pb.Refresh();
            pb.Optimize();

            // StaticEditorFlags flags = GameObjectUtility.GetStaticEditorFlags( pb.gameObject );

            // // if nodraw not found, and entity type should be batching static
            // if(pb.GetComponent<pb_Entity>().entityType != EntityType.Mover)
            // {
            //  flags = flags | StaticEditorFlags.BatchingStatic;
            //  GameObjectUtility.SetStaticEditorFlags(pb.gameObject, flags);
            // }
        }
Ejemplo n.º 26
0
    public override void OnInspectorGUI()
    {
        GUI.backgroundColor = Color.green;

        if (GUILayout.Button("Open " + pb_Constant.PRODUCT_NAME))
        {
            pb_Editor.MenuOpenWindow();
        }

        GUI.backgroundColor = Color.white;

        if (!ren)
        {
            return;
        }
        Vector3 sz = ren.bounds.size;

        EditorGUILayout.Vector3Field("Object Size (read only)", sz);

        if (pb == null)
        {
            return;
        }

        if (pb.SelectedTriangles.Length > 0)
        {
            GUILayout.Space(5);

            offset = EditorGUILayout.Vector3Field("Quick Offset", offset);

            if (GUILayout.Button("Apply Offset"))
            {
                pbUndo.RecordObject(pb, "Offset Vertices");

                pb.ToMesh();

                pb.TranslateVertices_World(pb.SelectedTriangles, offset);

                pb.Refresh();
                pb.Optimize();

                if (editor != null)
                {
                    editor.UpdateSelection();
                }
            }
        }
    }
Ejemplo n.º 27
0
        private static void SetTrigger(GameObject target)
        {
            pb_Object pb = target.GetComponent <pb_Object>();

                        #if !PROTOTYPE
            pb.SetFaceMaterial(pb.faces, pb_Constant.TriggerMaterial);
                        #else
            target.GetComponent <MeshRenderer>().sharedMaterial = pb_Constant.TriggerMaterial;
                        #endif

            SetIsTrigger(true, target);
            SetEditorFlags((StaticEditorFlags)0, target);

            pb.ToMesh();
            pb.Refresh();
        }
Ejemplo n.º 28
0
        private void AlignWithPreviewObject(GameObject go)
        {
            if (go == null || previewObject == null)
            {
                return;
            }
            go.transform.position   = previewObject.transform.position;
            go.transform.rotation   = previewObject.transform.rotation;
            go.transform.localScale = previewObject.transform.localScale;

            pb_Object pb = go.GetComponent <pb_Object>();

            pb.FreezeScaleTransform();
            pb.ToMesh();
            pb.Refresh();
        }
Ejemplo n.º 29
0
        /**
         * Projects UVs for each face using the closest normal on a box.
         */
        public static void ProjectFacesBox(pb_Object pb, pb_Face[] faces)
        {
            Vector2[] uv = pb.uv;

            Dictionary <ProjectionAxis, List <pb_Face> > sorted = new Dictionary <ProjectionAxis, List <pb_Face> >();

            for (int i = 0; i < faces.Length; i++)
            {
                Vector3        nrm  = pb_Math.Normal(pb, faces[i]);
                ProjectionAxis axis = pb_Math.VectorToProjectionAxis(nrm);

                if (sorted.ContainsKey(axis))
                {
                    sorted[axis].Add(faces[i]);
                }
                else
                {
                    sorted.Add(axis, new List <pb_Face>()
                    {
                        faces[i]
                    });
                }

                // clean up UV stuff - no shared UV indices and remove element group
                faces[i].elementGroup = -1;
            }

            foreach (KeyValuePair <ProjectionAxis, List <pb_Face> > kvp in sorted)
            {
                int[] distinct = pb_Face.AllTrianglesDistinct(kvp.Value.ToArray());

                Vector2[] uvs = pb_Math.PlanarProject(pb.GetVertices(distinct), pb_Math.ProjectionAxisToVector(kvp.Key), kvp.Key);

                for (int n = 0; n < distinct.Length; n++)
                {
                    uv[distinct[n]] = uvs[n];
                }

                SplitUVs(pb, distinct);
            }

            /* and set the msh uv array using the new coordintaes */
            pb.SetUV(uv);

            pb.ToMesh();
            pb.Refresh();
        }
Ejemplo n.º 30
0
    // bool pbInspectorFoldout = false;
    public override void OnInspectorGUI()
    {
        GUI.backgroundColor = Color.green;

        if (GUILayout.Button("Open " + pb_Constant.PRODUCT_NAME))
        {
            if (EditorPrefs.HasKey(pb_Constant.pbDefaultOpenInDockableWindow) &&
                !EditorPrefs.GetBool(pb_Constant.pbDefaultOpenInDockableWindow))
            {
                EditorWindow.GetWindow(typeof(pb_Editor), true, pb_Constant.PRODUCT_NAME, true);                                        // open as floating window
            }
            else
            {
                EditorWindow.GetWindow(typeof(pb_Editor), false, pb_Constant.PRODUCT_NAME, true);                                       // open as dockable window
            }
        }
        GUI.backgroundColor = Color.white;

        info = EditorGUILayout.Foldout(info, "Info");

        if (info)
        {
            Vector3 sz = ren.bounds.size;
            EditorGUILayout.Vector3Field("Object Size (read only)", sz);
        }

        if (pb == null)
        {
            return;
        }

        if (pb.SelectedTriangles.Length > 0)
        {
            offset = EditorGUILayout.Vector3Field("Quick Offset", offset);
            if (GUILayout.Button("Apply Offset"))
            {
                pbUndo.RecordObject(pb, "Offset Vertices");
                pb.TranslateVertices(pb.SelectedTriangles, offset);
                pb.Refresh();
                if (pb_Editor.instanceIfExists != null)
                {
                    pb_Editor.instance.UpdateSelection();
                }
            }
        }
    }
Ejemplo n.º 31
0
        private static void SetBrush(GameObject target)
        {
            EntityType et = target.GetComponent <pb_Entity>().entityType;

            if (et == EntityType.Trigger ||
                et == EntityType.Collider)
            {
                pb_Object pb = target.GetComponent <pb_Object>();

                                #if !PROTOTYPE
                pb.SetFaceMaterial(pb.faces, pb_Constant.DefaultMaterial);
                                #else
                target.GetComponent <MeshRenderer>().sharedMaterial = pb_Constant.DefaultMaterial;
                                #endif

                pb.ToMesh();
                pb.Refresh();
            }
        }
Ejemplo n.º 32
0
        public static bool DetachFacesToObject(this pb_Object pb, pb_Face[] faces, out pb_Object detachedObject)
        {
            detachedObject = null;

            if (faces.Length < 1 || faces.Length == pb.faces.Length)
            {
                return(false);
            }

            int[] primary = new int[faces.Length];
            for (int i = 0; i < primary.Length; i++)
            {
                primary[i] = System.Array.IndexOf(pb.faces, faces[i]);
            }

            int[] inverse = new int[pb.faces.Length - primary.Length];
            int   n       = 0;

            for (int i = 0; i < pb.faces.Length; i++)
            {
                if (System.Array.IndexOf(primary, i) < 0)
                {
                    inverse[n++] = i;
                }
            }

            detachedObject = pb_Object.InitWithObject(pb);

            detachedObject.transform.position      = pb.transform.position;
            detachedObject.transform.localScale    = pb.transform.localScale;
            detachedObject.transform.localRotation = pb.transform.localRotation;

            pb.DeleteFaces(primary);
            detachedObject.DeleteFaces(inverse);

            pb.Refresh();
            detachedObject.Refresh();

            detachedObject.gameObject.name = pb.gameObject.name + "-detach";

            return(true);
        }
Ejemplo n.º 33
0
    private static void SetPivot(pb_Object pbo, int[] testIndices, bool doSnap)
    {
        Vector3 center = Vector3.zero;
        foreach (Vector3 vector in pbo.VerticesInWorldSpace(testIndices))
        {
            center += vector;
        }
        center /= testIndices.Length;
            
        if(doSnap)
            center = pbUtil.SnapValue(center, Vector3.one, SixBySeven.Shared.snapValue);

        Vector3 dir = (pbo.transform.position - center);

        pbo.transform.position = center;

        // the last bool param force disables snapping vertices
        pbo.TranslateVertices(pbo.uniqueIndices, dir, true);
		
		pbo.Refresh();
    }
Ejemplo n.º 34
0
		/**
		 * Returns a jagged array of indices that share the same position, texture coordinate, and smoothing group.
		 * Must be called after Refresh() but before GenerateUV2().
		 */
		public static List<List<int>> FindDuplicateVertices(pb_Object pb)
		{
			Vector3[] normals = pb.msh.normals;

			if(pb.vertexCount != normals.Length)
			{
				pb.Refresh();
				normals = pb.msh.normals;
			}

			Color[] colors = pb.colors;
			Vector2[] textures = pb.uv;

			int[] smoothGroup = new int[normals.Length];

			/**
			 * Create a lookup of each triangles smoothing group.
			 */
			foreach(pb_Face face in pb.faces)
			{
				foreach(int tri in face.distinctIndices)
					smoothGroup[tri] = face.smoothingGroup;
			}

			List<int> list;
			List<List<int>> merge = new List<List<int>>();

			/**
			 * For each sharedIndices group (individual vertex), find vertices that are in the same smoothing
			 * group and check if their texture coordinates are similar enough to collapse to a single vertex.
			 */
			for(int i = 0; i < pb.sharedIndices.Length; i++)
			{
				Dictionary<int, List<int>> shareable = new Dictionary<int, List<int>>();

				/**
				 * Sort indices that share a smoothing group
				 */
				foreach(int tri in pb.sharedIndices[i].array)
				{
					if(smoothGroup[tri] > 24)	
						continue;

					if( shareable.TryGetValue(smoothGroup[tri], out list) )
						list.Add(tri);
					else
						shareable.Add(smoothGroup[tri], new List<int>() { tri });
				}

				/**
				 * At this point, `shareable` contains a key value pair of 
				 * { SmoothingGroupKey, All valid triangles pointing to this vertex }
				 */

				/**
				 * Now go through each key value pair and sort them into vertices that
				 * share a 'close enough' texture coordinate to be considered the same.
				 * Don't bother checking position since if they're in the same shared
				 * index group that should always means they're on top of one-another.
				 */

				foreach(KeyValuePair<int, List<int>> group in shareable)
				{			
					List<List<int>> matches = new List<List<int>>();

					foreach(int tri in group.Value)
					{
						bool foundMatch = false;

						for(int n = 0; n < matches.Count; n++)
						{
							if( textures[matches[n][0]].Approx(textures[tri], .001f) &&
								normals[matches[n][0]].Approx(normals[tri], .001f) &&
								(colors == null || colors[matches[n][0]].Approx(colors[tri], .001f)))
							{
								matches[n].Add(tri);
								foundMatch = true;
								break;
							}
						}

						if(!foundMatch)
							matches.Add( new List<int>() { tri } );
					}
	
					merge.AddRange( matches.Where(x => x.Count > 1) );
				}
			}

			return merge;
		}
Ejemplo n.º 35
0
	void OnSceneGUI(SceneView scnview)
	{
		if(!enabled)// || (EditorWindow.focusedWindow != scnview && !lockhandleToCenter))
			return;

		if(editor && editor.editLevel != EditLevel.Plugin)
			editor.SetEditLevel(EditLevel.Plugin);
 
// #if UNITY_5
// 		if( Lightmapping.giWorkflowMode == Lightmapping.GIWorkflowMode.Iterative )
// 		{
// 			pb_Lightmapping.PushGIWorkflowMode();
// 			Lightmapping.Cancel();
// 			Debug.LogWarning("Vertex Painter requires Continuous Baking to be Off.  When you close the Vertex Painter tool, Continuous Baking will returned to it's previous state automatically.\nIf you toggle Continuous Baking On while the Vertex Painter is open, you may lose all mesh vertex colors.");
// 		}
// #endif

		currentEvent = Event.current;
		sceneCamera = scnview.camera;

		screenCenter.x = Screen.width/2f;
		screenCenter.y = Screen.height/2f;

		mouseMoveEvent = currentEvent.type == EventType.MouseMove;
		
		/**
		 * Check if a new object is under the mouse.
		 */
		if( mouseMoveEvent )
		{
			GameObject go = HandleUtility.PickGameObject(Event.current.mousePosition, false);

			if( go != null && (pb == null || go != pb.gameObject) )
			{
				pb = go.GetComponent<pb_Object>();

				if(pb != null)
				{
					textures = GetTextures( pb.transform.GetComponent<MeshRenderer>().sharedMaterial ).ToArray();
					Repaint();

					modified.Add(pb);
					
					pb.ToMesh();
					pb.Refresh();
				}
			}
		}

		/**
		 * Hit test scene
		 */
		if(!lockhandleToCenter && !pb_Handle_Utility.SceneViewInUse(currentEvent))
		{
			if(pb != null)
			{
				if(!hovering.ContainsKey(pb))
				{
					hovering.Add(pb, pb.colors ?? new Color[pb.vertexCount]);
				}
				else
				{
					if(pb.msh.vertexCount != pb.vertexCount)
					{
						// script reload can make this happen
						pb.ToMesh();
						pb.Refresh();
					}

					pb.msh.colors = hovering[pb];
				}
 
				Ray ray = HandleUtility.GUIPointToWorldRay(currentEvent.mousePosition);
				pb_RaycastHit hit;

				if ( pb_Handle_Utility.MeshRaycast(ray, pb, out hit) )
				{
					handlePosition = pb.transform.TransformPoint(hit.Point);
					handleDistance = Vector3.Distance(handlePosition, sceneCamera.transform.position);					
					handleRotation = Quaternion.LookRotation(nonzero(pb.transform.TransformDirection(hit.Normal)), Vector3.up);
 
					Color[] colors = pb.msh.colors;

					int[][] sharedIndices = pb.sharedIndices.ToArray();

					// wrapped in try/catch because a script reload can cause the mesh
					// to re-unwrap itself in some crazy configuration, throwing off the 
					// vertex count sync.
					try
					{
						for(int i = 0; i < sharedIndices.Length; i++)
						{
							float dist = Vector3.Distance(hit.Point, pb.vertices[sharedIndices[i][0]]);

							if(dist < brushSize)
							{
								for(int n = 0; n < sharedIndices[i].Length; n++)
								{
									colors[sharedIndices[i][n]] = Lerp(hovering[pb][sharedIndices[i][n]], color, (1f-(dist/brushSize)) * brushOpacity );
								}
							}
						}
	 				} catch { /* shhhhh */ }

					// show a preview
					pb.msh.colors = colors;
				}
				else
				{
					// Clear
					foreach(KeyValuePair<pb_Object, Color[]> kvp in hovering)
						kvp.Key.msh.colors = kvp.Value;
 
					hovering.Clear();

					ray = HandleUtility.GUIPointToWorldRay(currentEvent.mousePosition);
					handleRotation = Quaternion.LookRotation(sceneCamera.transform.forward, Vector3.up);
					handlePosition = ray.origin + ray.direction * handleDistance;
				}
			}
		}
		else
		{
			// No longer focusing object
			foreach(KeyValuePair<pb_Object, Color[]> kvp in hovering)
			{
				kvp.Key.msh.colors = kvp.Value;
			}
 
			hovering.Clear();
 	
			Ray ray = HandleUtility.GUIPointToWorldRay(lockhandleToCenter ? screenCenter : currentEvent.mousePosition);
			handleRotation = Quaternion.LookRotation(sceneCamera.transform.forward, Vector3.up);
			handlePosition = ray.origin + ray.direction * handleDistance;
 		}

		/**
		*    Draw the handles
		*/
 		Handles.color = InnerRingColor;
			Handles.CircleCap(0, handlePosition, handleRotation, brushSize * .2f);
 		Handles.color = MiddleRingColor;
			Handles.CircleCap(0, handlePosition, handleRotation, brushSize * .5f);
 		Handles.color = OuterRingColor;		
			Handles.CircleCap(0, handlePosition, handleRotation, brushSize);
 		Handles.color = Color.white;
 
		// This prevents us from selecting other objects in the scene,
		// and allows for the selection of faces / vertices.
		int controlID = GUIUtility.GetControlID(FocusType.Passive);
		HandleUtility.AddDefaultControl(controlID);
 
		/**
		 * Apply colors to mesh
		 */
		if( (currentEvent.type == EventType.MouseDown || currentEvent.type == EventType.MouseDrag) &&
		   	(currentEvent.button == MOUSE_BUTTON_LEFT) &&
		   	currentEvent.modifiers == (EventModifiers)0 &&
		   	((CurTime - lastBrushApplication) > 1f/(brushStrength * BRUSH_STRENGTH_MAX)) )
		{
			lastBrushApplication = CurTime;

			Dictionary<pb_Object, Color[]> sticky = new Dictionary<pb_Object, Color[]>();
 	
			if(!isPainting)
			{
				Undo.RegisterCompleteObjectUndo(hovering.Keys.ToArray(), "Apply Vertex Colors");
				isPainting = true;
			}


 			// Apply colors
			foreach(KeyValuePair<pb_Object, Color[]> kvp in hovering)
			{
				Color[] colors = kvp.Key.msh.colors;

				sticky.Add(kvp.Key, colors);

				kvp.Key.SetColors(colors);
			}
 
			hovering = sticky;
		}

		if(currentEvent.control && currentEvent.type == EventType.ScrollWheel)
		{
			currentEvent.Use();
			brushSize += (currentEvent.delta.y > 0f ? -1f : 1f) * (brushSize * .1f);
			brushSize = Mathf.Clamp(brushSize, .01f, BRUSH_SIZE_MAX);

			Repaint();
		}

		if(currentEvent.type == EventType.MouseUp)
			isPainting = false;
 
		if(mpos != currentEvent.mousePosition && currentEvent.type == EventType.Repaint)
		{
			mpos = currentEvent.mousePosition;
			SceneView.RepaintAll();
		}
	}
Ejemplo n.º 36
0
	/**
	 *	\brief Given an array of "donors", this method returns a merged #pb_Object.
	 */
	 public static bool CombineObjects(pb_Object[] pbs, out pb_Object combined)
	 {
	 	combined = null;

	 	if(pbs.Length < 1) return false;

	 	List<Vector3> v = new List<Vector3>();
	 	List<Vector2> u = new List<Vector2>();
	 	List<Color> c = new List<Color>();
	 	List<pb_Face> f = new List<pb_Face>();
	 	List<pb_IntArray> s = new List<pb_IntArray>();
	 	List<pb_IntArray> suv = new List<pb_IntArray>();

	 	foreach(pb_Object pb in pbs)
	 	{
	 		int vertexCount = v.Count;

	 		// Vertices
	 		v.AddRange(pb.VerticesInWorldSpace());

	 		// UVs
	 		u.AddRange(pb.uv);

	 		// Colors
	 		c.AddRange(pb.colors);

			// Faces
	 		pb_Face[] faces = new pb_Face[pb.faces.Length];
	 		for(int i = 0; i < faces.Length; i++)
	 		{
	 			faces[i] = new pb_Face(pb.faces[i]);
	 			faces[i].manualUV = true;
	 			faces[i].ShiftIndices(vertexCount);
	 			faces[i].RebuildCaches();
	 		}
	 		f.AddRange(faces);

	 		// Shared Indices
	 		pb_IntArray[] si = pb.GetSharedIndices();
	 		for(int i = 0; i < si.Length; i++)
	 		{
	 			for(int n = 0; n < si[i].Length; n++)
	 				si[i][n] += vertexCount;
	 		}
	 		s.AddRange(si);

	 		// Shared Indices UV
	 		{
		 		pb_IntArray[] si_uv = pb.GetSharedIndicesUV();
		 		for(int i = 0; i < si_uv.Length; i++)
		 		{
		 			for(int n = 0; n < si_uv[i].Length; n++)
		 				si_uv[i][n] += vertexCount;
		 		}

		 		suv.AddRange(si_uv);
		 	}
	 	}

		GameObject go = (GameObject)GameObject.Instantiate(pbs[0].gameObject);
	 	go.transform.position = Vector3.zero;
	 	go.transform.localRotation = Quaternion.identity;
	 	go.transform.localScale = Vector3.one;

	 	// Destroy the children
	 	foreach(Transform t in go.transform)
	 		GameObject.DestroyImmediate(t.gameObject);

	 	if(go.GetComponent<pb_Object>()) GameObject.DestroyImmediate(go.GetComponent<pb_Object>());
	 	if(go.GetComponent<pb_Entity>()) GameObject.DestroyImmediate(go.GetComponent<pb_Entity>());

	 	combined = go.AddComponent<pb_Object>();

		combined.SetVertices(v.ToArray());
		combined.SetUV(u.ToArray());
		combined.SetColors(c.ToArray());
		combined.SetFaces(f.ToArray());

		combined.SetSharedIndices( s.ToArray() ?? pb_IntArrayUtility.ExtractSharedIndices(v.ToArray()) );
		combined.SetSharedIndicesUV( suv.ToArray() ?? new pb_IntArray[0] {});

		combined.ToMesh();

		combined.GetComponent<pb_Entity>().SetEntity( pbs[0].GetComponent<pb_Entity>().entityType );
	 	
	 	combined.CenterPivot( pbs[0].transform.position );

		combined.Refresh();

		// refresh donors since deleting the children of the instantiated object could cause them to lose references
		foreach(pb_Object pb in pbs)
			pb.Verify();

	 	return true;
	 }
Ejemplo n.º 37
0
	/**
	 * Projects UVs for each face using the closest normal on a box.
	 */
	public  static void ProjectFacesBox(pb_Object pb, pb_Face[] faces)
	{
		Vector2[] uv = pb.uv;

		Dictionary<ProjectionAxis, List<pb_Face>> sorted = new Dictionary<ProjectionAxis, List<pb_Face>>();

		for(int i = 0; i < faces.Length; i++)
		{
			Vector3 nrm = pb_Math.Normal(pb, faces[i]);
			ProjectionAxis axis = pb_Math.VectorToProjectionAxis(nrm);

			if(sorted.ContainsKey(axis))
			{
				sorted[axis].Add(faces[i]);
			}
			else
			{
				sorted.Add(axis, new List<pb_Face>() { faces[i] });
			}

			// clean up UV stuff - no shared UV indices and remove element group
			faces[i].elementGroup = -1;
		}

		foreach(KeyValuePair<ProjectionAxis, List<pb_Face>> kvp in sorted)
		{
			int[] distinct = pb_Face.AllTrianglesDistinct(kvp.Value.ToArray());

			Vector2[] uvs = pb_Math.PlanarProject( pb.GetVertices(distinct), pb_Math.ProjectionAxisToVector(kvp.Key), kvp.Key );

			for(int n = 0; n < distinct.Length; n++)
				uv[distinct[n]] = uvs[n];
				
			SplitUVs(pb, distinct);
		}

		/* and set the msh uv array using the new coordintaes */
		pb.SetUV(uv);
		
		pb.ToMesh();
		pb.Refresh();
	}
Ejemplo n.º 38
0
		/**
		 * Creates the icosphere, and loads all the cache information.
		 */
		void Start()
		{
			audioSource = GetComponent<AudioSource>();

			if( audioSource.clip == null )
				missingClipWarning.SetActive(true);

			// Create a new icosphere.
			ico = pb_ShapeGenerator.IcosahedronGenerator(icoRadius, icoSubdivisions);

			// Shell is all the faces on the new icosphere.
			pb_Face[] shell = ico.faces;
				
			// Materials are set per-face on pb_Object meshes.  pb_Objects will automatically
			// condense the mesh to the smallest set of subMeshes possible based on materials.
			foreach(pb_Face f in shell)
				f.SetMaterial( material );

			pb_Face[] connectingFaces;

			// Extrude all faces on the icosphere by a small amount.  The third boolean parameter
			// specifies that extrusion should treat each face as an individual, not try to group
			// all faces together.
			ico.Extrude(shell, startingExtrusion, false, out connectingFaces);

			// ToMesh builds the mesh positions, submesh, and triangle arrays.  Call after adding
			// or deleting vertices, or changing face properties.
			ico.ToMesh();

			// Refresh builds the normals, tangents, and UVs.
			ico.Refresh();

			outsides = new FaceRef[shell.Length];
			Dictionary<int, int> lookup = ico.sharedIndices.ToDictionary();

			// Populate the outsides[] cache.  This is a reference to the tops of each extruded column, including
			// copies of the sharedIndices.
			for(int i = 0; i < shell.Length; ++i)
				outsides[i] = new FaceRef( 	shell[i],
											pb_Math.Normal(ico, shell[i]),
											ico.sharedIndices.AllIndicesWithValues(lookup, shell[i].distinctIndices).ToArray()
											);

			// Store copy of positions array un-modified
			original_vertices = new Vector3[ico.vertices.Length];
			System.Array.Copy(ico.vertices, original_vertices, ico.vertices.Length);

			// displaced_vertices should mirror icosphere mesh vertices.
			displaced_vertices = ico.vertices;

			icoMesh = ico.msh;
			icoTransform = ico.transform;

			faces_length = (float)outsides.Length;

			// Build the waveform ring.
			icoPosition = icoTransform.position;
			waveform.SetVertexCount(WAVEFORM_SAMPLES);

			if( bounceWaveform )
				waveform.transform.parent = icoTransform;

			audioSource.Play();
		}
Ejemplo n.º 39
0
		private static void OnFaceChanged( pb_Object pb )
		{
			pb.ToMesh();
			pb.Refresh();
			pb.Optimize();
			
			// StaticEditorFlags flags = GameObjectUtility.GetStaticEditorFlags( pb.gameObject );
			
			// // if nodraw not found, and entity type should be batching static
			// if(pb.GetComponent<pb_Entity>().entityType != EntityType.Mover)
			// {
			// 	flags = flags | StaticEditorFlags.BatchingStatic;
			// 	GameObjectUtility.SetStaticEditorFlags(pb.gameObject, flags);
			// }
		}
Ejemplo n.º 40
0
	/**
	 * return true if shortcut should eat the event
	 */
	internal bool ClickShortcutCheck(pb_Object pb, pb_Face selectedFace)
	{
		Event e = Event.current;

		// Copy UV settings
		if(e.modifiers == (EventModifiers.Control | EventModifiers.Shift))
		{
			// get first selected Auto UV face
			pb_Object firstObj;
			pb_Face source;

			pb_Editor.instance.GetFirstSelectedFace(out firstObj, out source);

			if( source != null )
			{
				pbUndo.RecordObject(pb, "Copy UV Settings");

				selectedFace.SetUV( new pb_UV(source.uv) );
				selectedFace.SetMaterial( source.material );
				pb_Editor_Utility.ShowNotification("Copy UV Settings");

				pb.ToMesh();
				pb.Refresh();
				pb.Optimize();
				
				RefreshUVCoordinates();

				Repaint();
				
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		if(e.modifiers == EventModifiers.Control)
		{
			int len = pb.SelectedFaces == null ? 0 : pb.SelectedFaces.Length;

			if(len < 1)
				return false;

			pb_Face anchor = pb.SelectedFaces[len-1];

			if(anchor == selectedFace) return false;

			pbUndo.RecordObject(pb, "AutoStitch");

			pb.ToMesh();

			bool success = pbUVOps.AutoStitch(pb, anchor, selectedFace);
			
			if(success)
			{	
				RefreshElementGroups(pb);

				pb.SetSelectedFaces(new pb_Face[]{selectedFace});

				// // only need to do this for one pb_Object...
				// for(int i = 0; i < selection.Length; i++)
				// 	selection[i].RefreshUV( editor.SelectedFacesInEditZone[i] );

				pb.Refresh();
				pb.Optimize();

				SetSelectedUVsWithSceneView();

				RefreshUVCoordinates();

				pb_Editor_Utility.ShowNotification("Autostitch");

				if(editor != null)
					editor.UpdateSelection(false);

				Repaint();
			}
			else
			{
				pb.Refresh();
				pb.Optimize();
			}

			return success;
		}

		return false;
	}
Ejemplo n.º 41
0
	/**
	 * Deletes @faces from the passed pb_Object, and creates a new pb_Object using @faces.  On success,
	 * detachedObject will be set to the new pb_Object.
	 * 
	 * NOTE - As of 2.3, `DetachFacesToObject` was not publicly available in the pbMeshOps.  This method
	 * was made available in 2.3.1 as an extension method to pb_Object:
	 * `pbMeshOps::DetachFacesToObject(this pb_Object pb, pb_Face[] faces, out pb_Object detachedObject)`
	 */
	static bool DetachFacesToObject(pb_Object pb, pb_Face[] faces, out pb_Object detachedObject)
	{
		detachedObject = null;

		if(faces.Length < 1 || faces.Length == pb.faces.Length)
			return false;

		int[] primary = new int[faces.Length];
		for(int i = 0; i < primary.Length; i++)
			primary[i] = System.Array.IndexOf(pb.faces, faces[i]);
		
		int[] inverse = new int[pb.faces.Length - primary.Length];
		int n = 0;

		for(int i = 0; i < pb.faces.Length; i++)
			if(System.Array.IndexOf(primary, i) < 0)
				inverse[n++] = i;
				
		detachedObject = pb_Object.InitWithObject(pb);

		detachedObject.transform.position = pb.transform.position;
		detachedObject.transform.localScale = pb.transform.localScale;
		detachedObject.transform.localRotation = pb.transform.localRotation;

		pb.DeleteFaces(primary);
		detachedObject.DeleteFaces(inverse);

		pb.ToMesh();
		detachedObject.ToMesh();

		pb.Refresh();
		detachedObject.Refresh();
	
		detachedObject.gameObject.name = pb.gameObject.name + "-detach";
		
		return true;
	}
		void RefreshSelectedFacePreview()
		{
			pb_Face face = new pb_Face(currentSelection.face);	// Copy the currently selected face
			face.ShiftIndicesToZero();							// Shift the selected face indices to zero

			// Copy the currently selected vertices in world space.
			// World space so that we don't have to apply transforms
			// to match the current selection.
			Vector3[] verts = currentSelection.pb.VerticesInWorldSpace(currentSelection.face.distinctIndices);

			// Now go through and move the verts we just grabbed out about .1m from the original face.
			Vector3 normal = pb_Math.Normal(verts);

			for(int i = 0; i < verts.Length; i++)
				verts[i] += normal.normalized * .01f;

			if(preview)
				Destroy(preview.gameObject);

			preview = pb_Object.CreateInstanceWithVerticesFaces(verts, new pb_Face[1]{face});
			preview.SetFaceMaterial(preview.faces, previewMaterial);
			preview.ToMesh();
			preview.Refresh();
		}
Ejemplo n.º 43
0
		private static bool ConnectEdges(pb_Object pb, pb_Edge[] edgesToConnect)
		{	
			int len = edgesToConnect.Length;
			List<EdgeConnection> splits = new List<EdgeConnection>();

			for(int i = 0; i < len; i++)
			{
				foreach(pb_Face face in pbMeshUtils.GetConnectedFaces(pb, edgesToConnect[i]))
				{
					if(!splits.Contains((EdgeConnection)face))
					{
						List<pb_Edge> faceEdges = new List<pb_Edge>();
						foreach(pb_Edge e in edgesToConnect)
						{
							int localEdgeIndex = face.edges.IndexOf(e, pb.sharedIndices);
							if(localEdgeIndex > -1)
								faceEdges.Add(face.edges[localEdgeIndex]);
						}
	
						if(faceEdges.Count > 1)	
							splits.Add(new EdgeConnection(face, faceEdges));
					}
				}
			}

			pb_Face[] faces;
			if(pb.ConnectEdges(splits, out faces))
			{
				pb.SetSelectedFaces(faces);
				pb.GenerateUV2(true);
				pb.Refresh();
				return true;
			}
			return false;
		}