public override void OnInspectorGUI()
    {
        MeshSplit myScript = (MeshSplit)target;

        if (myScript.children != null && myScript.children.Count != 0)
        {
            EditorGUILayout.HelpBox("Submesh count: " + myScript.children.Count, MessageType.Info, true);
        }
        else
        {
            EditorGUILayout.HelpBox("Submesh count: none", MessageType.Info, true);
        }

        DrawDefaultInspector();

        if (GUILayout.Button("Split"))
        {
            myScript.Split();
        }

        if (GUILayout.Button("Clear"))
        {
            myScript.Clear();
        }
    }
Beispiel #2
0
        void Start()
        {
            mapJobs = new _MapJobs();
            mapJobs.processAsync(t => needUpdate = true);

            landzs = MeshSplit.createMesh(transform, "map mesh");
        }
Beispiel #3
0
    /// <summary>
    /// Performs fractal calls of MeshSplit.Split (no dependence on direction yet)
    /// </summary>
    public void Fracture(Vector3 point, float energy)
    {
        #region Cancellation Checks

        // If the mass is too small for further fragmentation, disable fractures
        if (GetComponent <Rigidbody>().mass < fragmentMinMass)
        {
            enabled = false;
            return;
        }
        // If the energy is insufficient for fragmentation, return
        else if (energy < Mathf.PI * minFractureRadius * minFractureRadius * fractureEnergy)
        {
            return;
        }

        #endregion Cancellation Checks

        #region Fracture Properties

        MeshCollider meshCollider = GetComponent <MeshCollider>();

        // breaks along lower energy planes should be more common
        Vector3 extents = meshCollider.bounds.extents * 1.73f;
        Vector3 normal  = Vector3.Scale(Random.onUnitSphere, Vector3.Scale(extents, extents)).normalized;

        Plane plane = new Plane(normal, point + Random.onUnitSphere * GetFaultDistance());
        // need a way to get the center of the bounds; what space is this in again? global?
        float planeDist2 = plane.GetDistanceToPoint(meshCollider.bounds.center);
        planeDist2 *= planeDist2;

        float crossSectionArea;
        if (planeDist2 / Vector3.Scale(normal, extents).sqrMagnitude > 1)
        {
            crossSectionArea = 0;
        }
        else if (normal.z == 1)
        {
            crossSectionArea = Mathf.PI * extents.x * extents.y * (1 - planeDist2 / (extents.z * extents.z));
        }
        else
        {
            Vector3 n2 = Vector3.Scale(normal, normal);
            Vector3 e2 = Vector3.Scale(extents, extents);
            float   v1 = extents.x * extents.y * extents.z;
            float   v2 = Vector3.Dot(e2, n2);
            float   u1 = n2.x + n2.y;
            float   u2 = e2.x * n2.x + e2.y * n2.y;
            float   u3 = e2.x * e2.x * n2.x + e2.y * e2.y * n2.y;
            crossSectionArea = Mathf.PI * v1 * (v2 - planeDist2) * Mathf.Sqrt(u1 * (u2 * u2 + u3 * n2.z)) / (u2 * Mathf.Sqrt(v2 * v2 * v2));
        }
        //print(": " + extents + " : " + crossSectionArea);

        // if the energy is too low to fracture, or the plane cannot intersect the object, cancel fragmentation
        if (crossSectionArea <= 0f || energy <= fractureEnergy * crossSectionArea)
        {
            return;
        }

        #endregion Fracture Properties

        #region Fracturing

        // set energy value for further fragmentation steps
        energy = (energy - fractureEnergy + surfaceEnergy * crossSectionArea) * 0.5f;

        // try to pull the other fragment from the object pool
        GameObject other = freeFragments.Count > 0 ? freeFragments.Pop() : Instantiate(gameObject);

        // attempt to fracture the object
        bool split = MeshSplit.Split(GetComponent <NMesh>(), other.GetComponent <NMesh>(), plane, Space.World);

        if (split)
        {
            other.SetActive(true);
            other.layer = gameObject.layer;

            Rigidbody       rigidbody         = GetComponent <Rigidbody>();
            PhysicsFracture otherFracture     = other.GetComponent <PhysicsFracture>();
            MeshCollider    otherMeshCollider = other.GetComponent <MeshCollider>();
            Rigidbody       otherRigidbody    = other.GetComponent <Rigidbody>();

            otherFracture.meanFaultDistance = meanFaultDistance;
            otherFracture.fractureEnergy    = fractureEnergy;
            otherFracture.surfaceEnergy     = surfaceEnergy;
            otherFracture.fragmentMinMass   = fragmentMinMass;

            meshCollider.sharedMesh          = GetComponent <MeshFilter>().mesh;
            otherMeshCollider.sharedMesh     = other.GetComponent <MeshFilter>().mesh;
            otherMeshCollider.sharedMaterial = meshCollider.sharedMaterial;

            Vector3 b0           = meshCollider.bounds.size;
            Vector3 b1           = otherMeshCollider.bounds.size;
            float   massFraction = 1.0f / (1.0f + ((b1.x / b0.x) * (b1.y / b0.y) * (b1.z / b0.z)));

            otherRigidbody.mass = rigidbody.mass * (1 - massFraction);
            rigidbody.mass     *= massFraction;

            //TODO: Consider copying all component properties. Possible without reflection?
            otherRigidbody.drag = rigidbody.drag;

            rigidbody.WakeUp();
            otherRigidbody.WakeUp();

            //TODO: Consider adding normal force from mesh split.
            //How much of the surface energy goes toward future fractures, and how much toward normal forces? Why?
            otherRigidbody.velocity        = rigidbody.velocity;
            otherRigidbody.angularVelocity = rigidbody.angularVelocity;

            otherFracture.Fracture(point, energy);
        }
        else
        {
            other.SetActive(false);
            freeFragments.Push(other);
        }

        Fracture(point, energy);

        #endregion Fracturing
    }
Beispiel #4
0
    void Update()
    {
        if (Input.GetMouseButtonDown(1))
        {
            start = Input.mousePosition;
            //start = new Vector3 (971, 247, 0);

            Ray        ray = Camera.main.ScreenPointToRay(start);
            RaycastHit hit;

            RaycastHit[] hits = Physics.RaycastAll(ray);

            if (Physics.Raycast(ray, out hit))
            {
                MeshSplit split = hit.collider.GetComponent <MeshSplit> ();
                if (split != null)
                {
                    startPoint = hit.point;

                    _meshsplit = split;

                    faceStart = hit.triangleIndex;

                    started = true;
                }
            }
        }
        else if (Input.GetMouseButtonUp(1) && started)
        {
            end = Input.mousePosition;
            //end = new Vector3 (1037, 126, 0);

            UnityEngine.Debug.LogFormat("{0} {1}", start, end);

            started = false;

            Ray        ray = Camera.main.ScreenPointToRay(end);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                MeshSplit split = hit.collider.GetComponent <MeshSplit> ();
                if (split != null && split == _meshsplit)
                {
                    endPoint = hit.point;

                    int fidx = hit.triangleIndex;

                    if (fidx == faceStart)
                    {
                        UnityEngine.Debug.LogWarning("face same!");
                        return;
                    }

                    float near = Camera.main.nearClipPlane;

                    Vector3 line = Camera.main.ScreenToWorldPoint(new Vector3(end.x, end.y, near)) - Camera.main.ScreenToWorldPoint(new Vector3(start.x, start.y, near));
                    line.Normalize();

                    Vector3 planeN = Vector3.Cross(line, ray.direction).normalized;


                    Vector3 center   = (startPoint + endPoint) / 2;
                    Vector3 offset   = endPoint - startPoint;
                    float   distance = Vector3.Dot(offset, line);

                    SplitPlane.transform.localRotation = Quaternion.identity;
                    SplitPlane.transform.forward       = planeN;

                    Vector3 dir   = (Camera.main.transform.position - center).normalized;
                    float   angle = Vector3.Angle(SplitPlane.transform.up, dir);
                    //UnityEngine.Debug.Log ("angle "+angle);

                    if (Vector3.Dot(SplitPlane.transform.right, dir) > 0)
                    {
                        angle = -angle;
                    }

                    Vector3 angles = SplitPlane.transform.eulerAngles;
                    SplitPlane.transform.localRotation = Quaternion.Euler(new Vector3(angles[0], angles[1], angle - angles[2]));
                    SplitPlane.transform.position      = (startPoint + endPoint) / 2f;
                    SplitPlane.transform.localScale    = new Vector3(distance, 1, 1);

                    // split
                    _meshsplit.Split(planeN, -SplitPlane.transform.up, startPoint, endPoint, faceStart, fidx);
                }
            }
        }
    }