示例#1
0
        private void CreateHullMapping()
        {
            if (hullMapping == null)
            {
                //	hullMapping = new Dictionary<Hull, Collider>();
                hullMapping = new List <HullMapping>();
            }

            // Remove any invalid entries from the hull mapping
            //	null entries are garbage and can be dropped
            //	null source hull means the hull has been deleted and this mapping is no longer relevant
            //	missing *both* generated collider *and* target child means there's no data to point at, so might as well remove it and regen from scratch
            for (int i = hullMapping.Count - 1; i >= 0; i--)
            {
                HullMapping mapping = hullMapping[i];
                if (mapping == null ||
                    mapping.sourceHull == null ||
                    (mapping.generatedCollider == null && mapping.targetChild == null))
                {
                    hullMapping.RemoveAt(i);
                }
            }

            // Check to see if any existing mappings need updating (hull.type doesn't match Collider type, or child type no longer matches)

            foreach (Hull hull in paintingData.hulls)
            {
                if (IsMapped(hull))
                {
                    // We already have a mapping for this, but is it still of the correct type?

                    Collider value = FindExistingCollider(hullMapping, hull);

                    bool isHullOk   = (hull.type == HullType.ConvexHull && value is MeshCollider);
                    bool isBoxOk    = (hull.type == HullType.Box && value is BoxCollider);
                    bool isSphereOk = (hull.type == HullType.Sphere && value is SphereCollider);
                    bool isFaceOk   = (hull.type == HullType.Face && value is MeshCollider);

                    bool isColliderTypeOk = (isHullOk || isBoxOk || isSphereOk || isFaceOk);
                    bool isChildTypeOk    = value == null || ((hull.isChildCollider) == (value.transform.parent == this.transform));

                    if (isColliderTypeOk && isChildTypeOk)
                    {
                        // All good
                    }
                    else
                    {
                        // Mismatch - hull.type doesn't match collider type
                        // Delete the collider and remove the mapping
                        // This hull will then be orphaned, and a new collider added back in accordingly
                        DestroyImmediateWithUndo(value);
                        RemoveMapping(hull);
                    }
                }
            }

            // Connect orphans
            //
            // Find hulls without a Collider
            // Find Colliders without hulls
            // Try and map the two together

            // First find orphans - hull, colliders or childs that aren't already mapped

            List <Hull>             orphanedHulls     = new List <Hull>();
            List <Collider>         orphanedColliders = new List <Collider>();
            List <HullPainterChild> orphanedChilds    = new List <HullPainterChild>();

            foreach (Hull h in paintingData.hulls)
            {
                if (!IsMapped(h))
                {
                    orphanedHulls.Add(h);
                }
            }

            foreach (Collider c in FindLocal <Collider>())
            {
                if (!IsMapped(c))
                {
                    orphanedColliders.Add(c);
                }
            }

            foreach (HullPainterChild c in FindLocal <HullPainterChild>())
            {
                if (!IsMapped(c))
                {
                    orphanedChilds.Add(c);
                }
            }

            // Try and connect orphaned hulls with orphaned colliders

            for (int i = orphanedHulls.Count - 1; i >= 0; i--)
            {
                Hull h = orphanedHulls[i];

                for (int j = orphanedColliders.Count - 1; j >= 0; j--)
                {
                    Collider c = orphanedColliders[j];

                    // Find the HullPainterChild adjacent to the collider (if a child collider)
                    HullPainterChild child = null;
                    if (c.transform.parent == this.transform)
                    {
                        child = c.gameObject.GetComponent <HullPainterChild>();
                    }

                    // todo needs better handling
                    bool isMatchingChild = h.isChildCollider && c.transform.parent == this.transform;
                    if (isMatchingChild)
                    {
                        BoxCollider    boxCol    = c as BoxCollider;
                        SphereCollider sphereCol = c as SphereCollider;
                        MeshCollider   meshCol   = c as MeshCollider;

                        bool isMatchingBox        = h.type == HullType.Box && c is BoxCollider && Approximately(h.collisionBox.center, boxCol.center) && Approximately(h.collisionBox.size, boxCol.size);
                        bool isMatchingSphere     = h.type == HullType.Sphere && c is SphereCollider && h.collisionSphere != null && Approximately(h.collisionSphere.center, sphereCol.center) && Approximately(h.collisionSphere.radius, sphereCol.radius);
                        bool isMatchingConvexHull = h.type == HullType.ConvexHull && c is MeshCollider && meshCol.sharedMesh == h.collisionMesh;
                        bool isMatchingFace       = h.type == HullType.Face && c is MeshCollider && meshCol.sharedMesh == h.faceCollisionMesh;

                        if (isMatchingBox || isMatchingSphere || isMatchingConvexHull || isMatchingFace)
                        {
                            // Found a pair, so add a mapping and remove the orphans
                            AddMapping(h, c, child);

                            // These are no longer orphaned, so remove them from these lists
                            orphanedHulls.RemoveAt(i);
                            orphanedColliders.RemoveAt(j);

                            // Remove the no-longer orphaned child
                            for (int k = 0; k < orphanedChilds.Count; k++)
                            {
                                if (orphanedChilds[k] == child)
                                {
                                    orphanedChilds.RemoveAt(k);
                                    break;
                                }
                            }

                            break;
                        }
                    }
                }
            }


            // We've tried to connect hulls to existing colliders, now try and connect hulls to existing HullPainterChilds
            // These will be child without a collider (as otherwise they'd have be picked up earlier)
            for (int i = orphanedHulls.Count - 1; i >= 0; i--)
            {
                Hull h = orphanedHulls[i];

                if (!h.isChildCollider)
                {
                    continue;
                }

                for (int j = orphanedChilds.Count - 1; j >= 0; j--)
                {
                    HullPainterChild child   = orphanedChilds[j];
                    HullMapping      mapping = FindMapping(child);

                    if (mapping != null && mapping.sourceHull != null)
                    {
                        // Found a match for hull-mapping-child

                        // Ensure this still has a collider
                        if (mapping.generatedCollider == null)
                        {
                            // Recreate the collider of the correct type with the existing hull-mapping-child

                            RecreateChildCollider(mapping);
                        }

                        orphanedHulls.RemoveAt(i);
                        orphanedChilds.RemoveAt(j);
                        break;
                    }
                }
            }

            // Create colliders for any hull mapping children without colliders
            foreach (HullMapping mapping in hullMapping)
            {
                if (mapping.targetChild != null && mapping.generatedCollider == null)
                {
                    RecreateChildCollider(mapping);
                }
            }

            // Create child components for child colliders without them
            foreach (HullMapping mapping in hullMapping)
            {
                if (mapping.targetChild == null && mapping.generatedCollider != null && mapping.generatedCollider.transform.parent == this.transform)
                {
                    // Mapping has a child collider but no HullPainterChild
                    // Recreate the child component
                    HullPainterChild newChild = AddComponent <HullPainterChild>(mapping.generatedCollider.gameObject);
                    newChild.parent     = this;
                    mapping.targetChild = newChild;
                }
            }

            // Create colliders for any left over hulls

            foreach (Hull h in orphanedHulls)
            {
                if (h.type == HullType.Box)
                {
                    CreateCollider <BoxCollider>(h);
                }
                else if (h.type == HullType.Sphere)
                {
                    CreateCollider <SphereCollider>(h);
                }
                else if (h.type == HullType.ConvexHull)
                {
                    CreateCollider <MeshCollider>(h);
                }
                else if (h.type == HullType.Face)
                {
                    CreateCollider <MeshCollider>(h);
                }
            }

            // Delete any left over colliders
            // TODO: This probably isn't properly undo-aware

            foreach (Collider c in orphanedColliders)
            {
                if (c.gameObject == this.gameObject)
                {
                    DestroyImmediateWithUndo(c);
                }
                else
                {
                    // Child collider - delete collider, HullPainterChild (if any) and GameObject (if empty)

                    GameObject go = c.gameObject;
                    DestroyImmediateWithUndo(c);
                    DestroyImmediateWithUndo(go.GetComponent <HullPainterChild>());
                    if (IsDeletable(go))
                    {
                        DestroyImmediateWithUndo(go);
                    }
                }
            }

            // Delete any left over hull painter childs
            // TODO: This probably isn't undo-aware

            foreach (HullPainterChild child in orphanedChilds)
            {
                if (child == null)
                {
                    continue;
                }

                // Delete child, collider (if any) and GameObject (if empty)
                GameObject go = child.gameObject;
                DestroyImmediateWithUndo(child);
                DestroyImmediateWithUndo(go.GetComponent <Collider>());
                if (IsDeletable(go))
                {
                    DestroyImmediateWithUndo(go);
                }
            }

            // Sanity check - all hull mappings should have a collider of the right type now
            //	foreach (HullMapping mapping in hullMapping)
            //	{
            //		if (mapping.generatedCollider == null)
            //			Debug.LogWarning("Null collider for hull: " + mapping.sourceHull.name);
            //	}
        }
        private void CreateHullMapping()
        {
            if (hullMapping == null)
            {
                hullMapping = new Dictionary <Hull, Collider> ();
            }

            List <Hull> keys = new List <Hull> (hullMapping.Keys);           // take a copy of the keys so we can remove from hullMapping as we iterate over it

            foreach (Hull h in keys)
            {
                if (h == null || hullMapping[h] == null)
                {
                    Debug.Log("Removing invalid entry from hull mapping");
                    hullMapping.Remove(h);
                }
            }

            // Check to see if any existing mappings need updating (hull.type doesn't match Collider type)

            foreach (Hull hull in paintingData.hulls)
            {
                if (hullMapping.ContainsKey(hull))
                {
                    // We already have a mapping for this, but is it still of the correct type?

                    Collider value = hullMapping[hull];

                    bool isHullOk   = (hull.type == HullType.ConvexHull && value is MeshCollider);
                    bool isBoxOk    = (hull.type == HullType.Box && value is BoxCollider);
                    bool isSphereOk = (hull.type == HullType.Sphere && value is SphereCollider);
                    bool isFaceOk   = (hull.type == HullType.Face && value is MeshCollider);

                    if (!(isHullOk || isBoxOk || isSphereOk || isFaceOk))
                    {
                        // Mismatch - hull.type doesn't match collider type
                        // Delete the collider and remove the mapping
                        // This hull will then be orphaned, and a new collider added back in accordingly
                        GameObject.DestroyImmediate(value);
                        hullMapping.Remove(hull);
                    }
                }
            }

            // Connect orphans
            //
            // Find hulls without a Collider
            // Find Colliders without hulls
            // Try and map the two together

            // First find orphans

            List <Hull>     orphanedHulls     = new List <Hull> ();
            List <Collider> orphanedColliders = new List <Collider> ();

            foreach (Hull h in paintingData.hulls)
            {
                if (!hullMapping.ContainsKey(h))
                {
                    orphanedHulls.Add(h);
                }
            }

            foreach (Collider c in GetComponents <Collider>())
            {
                if (!hullMapping.ContainsValue(c))
                {
                    orphanedColliders.Add(c);
                }
            }

            // Try and connect orphaned hulls with orphaned colliders

            for (int i = orphanedHulls.Count - 1; i >= 0; i--)
            {
                Hull h = orphanedHulls[i];

                for (int j = orphanedColliders.Count - 1; j >= 0; j--)
                {
                    Collider c = orphanedColliders[j];

                    BoxCollider    boxCol    = c as BoxCollider;
                    SphereCollider sphereCol = c as SphereCollider;
                    MeshCollider   meshCol   = c as MeshCollider;

                    bool isMatchingBox        = h.type == HullType.Box && c is BoxCollider && Approximately(h.collisionBox.center, boxCol.center) && Approximately(h.collisionBox.size, boxCol.size);
                    bool isMatchingSphere     = h.type == HullType.Sphere && c is SphereCollider && h.collisionSphere != null && Approximately(h.collisionSphere.center, sphereCol.center) && Approximately(h.collisionSphere.radius, sphereCol.radius);
                    bool isMatchingConvexHull = h.type == HullType.ConvexHull && c is MeshCollider && meshCol.sharedMesh == h.collisionMesh;
                    bool isMatchingFace       = h.type == HullType.Face && c is MeshCollider && meshCol.sharedMesh == h.faceCollisionMesh;

                    if (isMatchingBox || isMatchingSphere || isMatchingConvexHull || isMatchingFace)
                    {
                        // Found a pair, so add a mapping and remove the orphans
                        hullMapping.Add(h, c);

                        // These are no longer orphaned, so remove them from these lists
                        orphanedHulls.RemoveAt(i);
                        orphanedColliders.RemoveAt(j);
                        break;
                    }
                }
            }

            // Create colliders for any left over hulls

            foreach (Hull h in orphanedHulls)
            {
                if (h.type == HullType.Box)
                {
#if UNITY_EDITOR
                    BoxCollider box = (BoxCollider)Undo.AddComponent(this.gameObject, typeof(BoxCollider));
#else
                    BoxCollider box = this.gameObject.AddComponent <BoxCollider>();
#endif
                    hullMapping.Add(h, box);
                }
                else if (h.type == HullType.Sphere)
                {
#if UNITY_EDITOR
                    SphereCollider sphere = (SphereCollider)Undo.AddComponent(this.gameObject, typeof(SphereCollider));
#else
                    SphereCollider sphere = this.gameObject.AddComponent <SphereCollider>();
#endif
                    hullMapping.Add(h, sphere);
                }
                else if (h.type == HullType.ConvexHull)
                {
#if UNITY_EDITOR
                    MeshCollider mesh = (MeshCollider)Undo.AddComponent(this.gameObject, typeof(MeshCollider));
#else
                    MeshCollider mesh = this.gameObject.AddComponent <MeshCollider>();
#endif
                    hullMapping.Add(h, mesh);
                }
                else if (h.type == HullType.Face)
                {
#if UNITY_EDITOR
                    MeshCollider mesh = (MeshCollider)Undo.AddComponent(this.gameObject, typeof(MeshCollider));
#else
                    MeshCollider mesh = this.gameObject.AddComponent <MeshCollider>();
#endif
                    hullMapping.Add(h, mesh);
                }
            }

            // Delete any left over colliders

            foreach (Collider c in orphanedColliders)
            {
                GameObject.DestroyImmediate(c);
            }
        }
示例#3
0
        private void DrawHullGUILine(int hullIndex, Hull hull, Dictionary <Collumn, GUILayoutOption> widths, Dictionary <Collumn, float> rawWidths)
        {
            HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter();

            Undo.RecordObject(currentHullPainter.paintingData, "Edit Hull");

            GUILayout.BeginHorizontal();
            {
                if (IsCollumnVisible(Collumn.Visibility))
                {
                    if (GUILayout.Button(hull.isVisible ? hullVisibleIcon : hullInvisibleIcon, EditorStyles.miniButton, GUILayout.Height(16), widths[Collumn.Visibility]))
                    {
                        hull.isVisible    = !hull.isVisible;
                        regenerateOverlay = true;
                    }
                }

                if (IsCollumnVisible(Collumn.Name))
                {
                    hull.name = EditorGUILayout.TextField(hull.name, GUILayout.MinWidth(60), widths[Collumn.Name]);
                }

                if (IsCollumnVisible(Collumn.Colour))
                {
                    Color prevColour = hull.colour;
                    hull.colour = EditorGUILayout.ColorField("", hull.colour, widths[Collumn.Colour]);
                    if (prevColour != hull.colour)
                    {
                        regenerateOverlay = true;
                        repaintSceneView  = true;
                    }
                }

                if (IsCollumnVisible(Collumn.Type))
                {
                    hull.type = (HullType)EditorGUILayout.EnumPopup(hull.type, widths[Collumn.Type]);
                }

                if (IsCollumnVisible(Collumn.Material))
                {
                    hull.material = (PhysicMaterial)EditorGUILayout.ObjectField(hull.material, typeof(PhysicMaterial), false, widths[Collumn.Material]);
                }

                if (IsCollumnVisible(Collumn.Inflate))
                {
                    float toggleSize = 12;
                    float floatSize  = rawWidths[Collumn.Inflate] - toggleSize - 4;

                    hull.enableInflation = EditorGUILayout.Toggle(hull.enableInflation, GUILayout.Width(toggleSize));
                    hull.inflationAmount = EditorGUILayout.FloatField(hull.inflationAmount, GUILayout.Width(floatSize));
                }

                if (IsCollumnVisible(Collumn.IsChild))
                {
                    if (GUILayout.Button(hull.isChildCollider ? isChildIcon : nonChildIcon, EditorStyles.miniButton, widths[Collumn.IsChild]))
                    {
                        hull.isChildCollider = !hull.isChildCollider;
                    }
                }

                if (IsCollumnVisible(Collumn.Trigger))
                {
                    if (GUILayout.Button(hull.isTrigger ? triggerOnIcon : triggerOffIcon, EditorStyles.miniButton, widths[Collumn.Trigger]))
                    {
                        hull.isTrigger = !hull.isTrigger;
                    }
                }

                if (IsCollumnVisible(Collumn.Paint))
                {
                    int prevHullIndex = currentHullPainter.paintingData.activeHull;

                    bool isPainting  = (currentHullPainter.paintingData.activeHull == hullIndex);
                    int  nowSelected = GUILayout.Toolbar(isPainting ? 0 : -1, new Texture[] { isPainting?paintOnIcon: paintOffIcon }, EditorStyles.miniButton, widths[Collumn.Paint]);
                    if (nowSelected == 0 && prevHullIndex != hullIndex)
                    {
                        // Now painting this index!
                        currentHullPainter.paintingData.activeHull = hullIndex;
                    }
                }

                if (IsCollumnVisible(Collumn.Delete))
                {
                    if (GUILayout.Button(deleteIcon, EditorStyles.miniButton, widths[Collumn.Delete]))
                    {
                        hullToDelete      = hullIndex;
                        regenerateOverlay = true;
                        repaintSceneView  = true;
                    }
                }
            }
            GUILayout.EndHorizontal();
        }
示例#4
0
        private void GenerateConvexHull(Hull hull, Vector3[] meshVertices, int[] meshIndices, Mesh destMesh)
        {
            // Generate array of input points

            int totalFaces = hull.selectedFaces.Count;

            Point3d[] inputPoints = new Point3d[totalFaces * 3];

            for (int i = 0; i < hull.selectedFaces.Count; i++)
            {
                int faceIndex = hull.selectedFaces[i];

                Vector3 p0 = meshVertices[meshIndices[faceIndex * 3]];
                Vector3 p1 = meshVertices[meshIndices[faceIndex * 3 + 1]];
                Vector3 p2 = meshVertices[meshIndices[faceIndex * 3 + 2]];

                inputPoints[i * 3]     = new Point3d(p0.x, p0.y, p0.z);
                inputPoints[i * 3 + 1] = new Point3d(p1.x, p1.y, p1.z);
                inputPoints[i * 3 + 2] = new Point3d(p2.x, p2.y, p2.z);
            }

            // Calculate the convex hull

            QuickHull3D qHull = new QuickHull3D();

            try
            {
                qHull.build(inputPoints);
            }
            catch (System.Exception)
            {
                Debug.LogError("Could not generate hull for " + this.name + "'s '" + hull.name + "' (input " + inputPoints.Length + " points)");
            }

            // Get calculated hull vertices and indices

            Point3d[] hullVertices    = qHull.getVertices();
            int[][]   hullFaceIndices = qHull.getFaces();

            hull.numColliderFaces = hullFaceIndices.Length;

            Debug.Log("Calculated collider for '" + hull.name + "' has " + hullFaceIndices.Length + " faces");
            if (hullFaceIndices.Length >= 256)
            {
                hull.hasColliderError = true;
                return;
            }

            // Convert to dest vertices

            Vector3[] destVertices = new Vector3[hullVertices.Length];
            for (int i = 0; i < destVertices.Length; i++)
            {
                destVertices[i] = new Vector3((float)hullVertices[i].x, (float)hullVertices[i].y, (float)hullVertices[i].z);
            }

            // Convert to dest incices

            List <int> destIndices = new List <int>();

            for (int i = 0; i < hullFaceIndices.Length; i++)
            {
                int faceVerts = hullFaceIndices[i].Length;
                for (int j = 1; j < faceVerts - 1; j++)
                {
                    destIndices.Add(hullFaceIndices[i][0]);
                    destIndices.Add(hullFaceIndices[i][j]);
                    destIndices.Add(hullFaceIndices[i][j + 1]);
                }
            }

            int[] destIndicesArray = new int[destIndices.Count];
            for (int i = 0; i < destIndices.Count; i++)
            {
                destIndicesArray[i] = destIndices[i];
            }

            // Push to collision mesh

            hull.collisionMesh.vertices  = destVertices;
            hull.collisionMesh.triangles = destIndicesArray;
            hull.collisionMesh.RecalculateBounds();
        }
示例#5
0
        public void GenerateCollisionMesh(Hull hull, Vector3[] meshVertices, int[] meshIndices)
        {
            hull.hasColliderError = false;

            if (hull.type == HullType.Box)
            {
                if (hull.selectedFaces.Count > 0)
                {
                    Vector3 first = meshVertices[meshIndices[hull.selectedFaces[0] * 3]];

                    Vector3 min = first;
                    Vector3 max = first;

                    for (int i = 0; i < hull.selectedFaces.Count; i++)
                    {
                        int faceIndex = hull.selectedFaces[i];

                        Vector3 p0 = meshVertices[meshIndices[faceIndex * 3]];
                        Vector3 p1 = meshVertices[meshIndices[faceIndex * 3 + 1]];
                        Vector3 p2 = meshVertices[meshIndices[faceIndex * 3 + 2]];

                        Inflate(p0, ref min, ref max);
                        Inflate(p1, ref min, ref max);
                        Inflate(p2, ref min, ref max);
                    }

                    hull.collisionBox.center = (min + max) * 0.5f;
                    hull.collisionBox.size   = max - min;
                }
            }
            else if (hull.type == HullType.Sphere)
            {
                Vector3 sphereCenter;
                float   sphereRadius;
                if (CalculateBoundingSphere(hull, meshVertices, meshIndices, out sphereCenter, out sphereRadius))
                {
                    if (hull.collisionSphere == null)
                    {
                        hull.collisionSphere = new Sphere();
                    }

                    hull.collisionSphere.center = sphereCenter;
                    hull.collisionSphere.radius = sphereRadius;
                }
            }
            else if (hull.type == HullType.ConvexHull)
            {
                if (hull.collisionMesh == null)
                {
                    hull.collisionMesh = new Mesh();
                }

                hull.collisionMesh.name = hull.name;

                hull.collisionMesh.triangles = new int[0];
                hull.collisionMesh.vertices  = new Vector3[0];

                GenerateConvexHull(hull, meshVertices, meshIndices, hull.collisionMesh);
            }
            else if (hull.type == HullType.Face)
            {
                if (hull.faceCollisionMesh == null)
                {
                    hull.faceCollisionMesh = new Mesh();
                }

                hull.faceCollisionMesh.name = hull.name;

                hull.faceCollisionMesh.triangles = new int[0];
                hull.faceCollisionMesh.vertices  = new Vector3[0];

                GenerateFace(hull, meshVertices, meshIndices, faceThickness);
            }
        }
示例#6
0
        private void SyncOverlay(HullPainter hullPainter)
        {
            //	Debug.Log ("SyncOverlay - overlayObject: " + overlayObject);

            if (hullPainter != null && hullPainter.paintingData != null)
            {
                int totalFaces = 0;
                for (int i = 0; i < hullPainter.paintingData.hulls.Count; i++)
                {
                    Hull hull = hullPainter.paintingData.hulls[i];
                    if (hull.isVisible)
                    {
                        totalFaces += hull.selectedFaces.Count;
                    }
                }

                //		Debug.Log("Overlay has "+totalFaces+" faces");


                Vector3[] vertices = new Vector3[totalFaces * 3];
                Color[]   colours  = new Color[totalFaces * 3];
                int[]     indices  = new int[totalFaces * 3];

                // Rebuild vertex buffers

                int nextIndex = 0;

                for (int i = 0; i < hullPainter.paintingData.hulls.Count; i++)
                {
                    Hull hull = hullPainter.paintingData.hulls[i];

                    if (!hull.isVisible)
                    {
                        continue;
                    }

                    for (int j = 0; j < hull.selectedFaces.Count; j++)
                    {
                        int faceIndex = hull.selectedFaces[j];

                        int i0 = faceIndex * 3;
                        int i1 = faceIndex * 3 + 1;
                        int i2 = faceIndex * 3 + 2;

                        if (i0 < targetTriangles.Length &&
                            i1 < targetTriangles.Length &&
                            i2 < targetTriangles.Length)
                        {
                            int t0 = targetTriangles[i0];
                            int t1 = targetTriangles[i1];
                            int t2 = targetTriangles[i2];

                            if (t0 < targetVertices.Length && t1 < targetVertices.Length && t2 < targetVertices.Length)
                            {
                                Vector3 p0 = targetVertices[t0];
                                Vector3 p1 = targetVertices[t1];
                                Vector3 p2 = targetVertices[t2];

                                colours[nextIndex]     = hull.colour;
                                colours[nextIndex + 1] = hull.colour;
                                colours[nextIndex + 2] = hull.colour;

                                vertices[nextIndex]     = p0;
                                vertices[nextIndex + 1] = p1;
                                vertices[nextIndex + 2] = p2;

                                nextIndex += 3;
                            }
                            else
                            {
                                Debug.LogWarning("Skipping face because vertex index out of bounds");
                            }
                        }
                        else
                        {
                            Debug.LogWarning("Skipping face because triangle index out of bounds: " + faceIndex);

                            // TODO: Should we advance nextIndex or not?
                            // Maybe we should have a validate step rather than trying to solve this problem now?
                        }
                    }
                }

                // Generate the indices
                for (int i = 0; i < indices.Length; i++)
                {
                    indices [i] = i;
                }

                Mesh overlayMesh = overlayFilter.sharedMesh;
                overlayMesh.triangles = new int[0];
                overlayMesh.vertices  = vertices;
                overlayMesh.colors    = colours;
                overlayMesh.triangles = indices;

                overlayFilter.sharedMesh = overlayMesh;

                overlayRenderer.enabled = true;
            }
            else
            {
                // No hull painter selected, clear everything

                overlayFilter.sharedMesh.Clear();
                overlayRenderer.enabled = false;
            }
        }
示例#7
0
        public bool DoMouseDown(PickMode initialMode)
        {
            if (currentToolSelection == ToolSelection.TrianglePainting)
            {
                if (targetMeshCollider != null)
                {
                    if (currentHullPainter != null && currentHullPainter.paintingData != null)
                    {
                        Undo.RecordObject(currentHullPainter.paintingData, "Paint Hull");

                        pickMode = PickTriangle(initialMode);
                        if (pickMode != PickMode.Undecided)
                        {
                            //	Debug.Log ("Start drag");

                            Sync();

                            EditorUtility.SetDirty(currentHullPainter.paintingData);

                            isSelectingFaces = true;

                            return(true);
                        }
                        else
                        {
                            //	Debug.Log ("Abandon drag");
                        }
                    }
                    else
                    {
                        // This can happen when unity triggers scene callbacks in an odd order and the currentHullPainter isn't set yet
                        //	Debug.LogError("SceneManipulator has no currentHullPainter!");
                    }
                }
                else
                {
                    Debug.Log("Mouse down but no targetMeshCollider, ignoring");
                }
            }
            else if (currentToolSelection == ToolSelection.Pipette)
            {
                // Raycast against the target mesh collider and see if the triangle we hit is in any current hull

                bool anyFound = false;

                Ray pickRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

                int hitTriIndex = -1;
                if (targetMeshCollider != null && RaycastUtil.Raycast(targetMeshCollider, pickRay, out hitTriIndex, 10000.0f))
                {
                    for (int i = 0; i < currentHullPainter.paintingData.hulls.Count; i++)
                    {
                        Hull hull = currentHullPainter.paintingData.hulls[i];
                        if (hull.selectedFaces.Contains(hitTriIndex))
                        {
                            // Now painting this hull!
                            currentHullPainter.paintingData.activeHull = i;
                            currentToolSelection = ToolSelection.TrianglePainting;
                            anyFound             = true;
                            break;
                        }
                    }
                }

                if (!anyFound)
                {
                    currentToolSelection = ToolSelection.TrianglePainting;
                    currentHullPainter.paintingData.activeHull = -1;
                }
            }

            return(false);
        }
示例#8
0
        private void SyncOverlay(HullPainter hullPainter)
        {
            //	Debug.Log ("SyncOverlay - overlayObject: " + overlayObject);

            if (hullPainter != null && hullPainter.paintingData != null)
            {
                int totalFaces = 0;
                for (int i = 0; i < hullPainter.paintingData.hulls.Count; i++)
                {
                    totalFaces += hullPainter.paintingData.hulls[i].selectedFaces.Count;
                }

                //		Debug.Log("Overlay has "+totalFaces+" faces");


                Vector3[] vertices = new Vector3[totalFaces * 3];
                Color[]   colours  = new Color[totalFaces * 3];
                int[]     indices  = new int[totalFaces * 3];

                // Rebuild vertex buffers

                int nextIndex = 0;

                for (int i = 0; i < hullPainter.paintingData.hulls.Count; i++)
                {
                    Hull hull = hullPainter.paintingData.hulls[i];

                    for (int j = 0; j < hull.selectedFaces.Count; j++)
                    {
                        int     faceIndex = hull.selectedFaces[j];
                        Vector3 p0        = targetVertices[targetTriangles[faceIndex * 3 + 0]];
                        Vector3 p1        = targetVertices[targetTriangles[faceIndex * 3 + 1]];
                        Vector3 p2        = targetVertices[targetTriangles[faceIndex * 3 + 2]];

                        colours[nextIndex]     = hull.colour;
                        colours[nextIndex + 1] = hull.colour;
                        colours[nextIndex + 2] = hull.colour;

                        vertices[nextIndex]     = p0;
                        vertices[nextIndex + 1] = p1;
                        vertices[nextIndex + 2] = p2;

                        nextIndex += 3;
                    }
                }

                // Generate the indices
                for (int i = 0; i < indices.Length; i++)
                {
                    indices [i] = i;
                }

                Mesh overlayMesh = overlayFilter.sharedMesh;
                overlayMesh.triangles = new int[0];
                overlayMesh.vertices  = vertices;
                overlayMesh.colors    = colours;
                overlayMesh.triangles = indices;

                overlayFilter.sharedMesh = overlayMesh;

                overlayRenderer.enabled = true;
            }
            else
            {
                // No hull painter selected, clear everything

                overlayFilter.sharedMesh.Clear();
                overlayRenderer.enabled = false;
            }
        }