Beispiel #1
0
    private void OnTriggerEnter2D(Collider2D collider)
    {
        if (collider.gameObject.layer == LayerMask.NameToLayer("Bullet"))
        {
            float area = meshData.GetArea();

            GameManager.Instance.mainCamera.GetComponent <CameraShake>().InduceMotion(area / (transform.position - GameManager.Instance.playerController.transform.position).magnitude);

            if (area < parentGenerator.areaThreshold)
            {
                gameObject.SetActive(false);
                ScoreSystem.Instance.IncreaseScore((long)destructionPoints);
                AudioManager.Instance.PlaySoundAtPosition(destructionSFX, transform.position);
            }
            else
            {
                Vector3 vel = collider.GetComponent <Rigidbody2D>().velocity;

                MeshData[] slices = MeshSlicer.Slice(meshData, vel, collider.transform.position, transform.position, transform.rotation, out Vector2 posCentroid, out Vector2 negCentroid);
                collider.gameObject.SetActive(false);

                if (slices == null)
                {
                    return;
                }

                gameObject.SetActive(false);

                parentGenerator.GenerateAsteroidSlices(slices[0], slices[1], negCentroid, posCentroid, rb2D.velocity, vel);

                ScoreSystem.Instance.IncreaseScore((long)divisionPoints);
            }
        }
    }
Beispiel #2
0
    void Update()
    {
        if (Input.GetMouseButtonUp(0))
        {
            Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit rayCastHitInfo = default(RaycastHit);
            if (Physics.Raycast(cameraRay, out rayCastHitInfo))
            {
                Mesh originMesh = rayCastHitInfo.collider.gameObject.GetComponent <MeshFilter>().sharedMesh;

                Vector3 slicerNormal  = rayCastHitInfo.normal;
                Vector3 pointOnSlicer = rayCastHitInfo.point - slicerNormal * SlicerOffset;
                Plane   slicerPlane   = new Plane(slicerNormal, pointOnSlicer);

                Matrix4x4 trs = Matrix4x4.TRS(rayCastHitInfo.collider.gameObject.transform.position, rayCastHitInfo.collider.gameObject.transform.rotation, rayCastHitInfo.collider.gameObject.transform.localScale);

                Mesh m = Object.Instantiate <Mesh>(originMesh);
                m.ApplyTransposeMatrix(trs);

                MeshSlicer slicer = new MeshSlicer(m, slicerPlane);


                slicer.Slice(false, false);

                slicer.RenderSlicedGameObject(SlicedUpperMaterial);
            }
        }
    }
    public void CutMesh()
    {
        if (GeneratedMeshes.Count <= 0)
        {
            return;
        }

        var meshToCut = GeneratedMeshes[0];

        // test out cut
        Mesh[] meshParts = MeshSlicer.Slice(meshToCut.Mesh, CuttingPlanePosition, CuttingPlaneNormal.normalized);
        for (int i = 0; i < meshParts.Length; i++)
        {
            Mesh m = meshParts[i];
            m.RecalculateNormals();
            m.RecalculateBounds();
            m.RecalculateTangents();

            var generatedMesh = ObjectCreator.CreateSciptableMesh($"meshPart{i + 1} (Generated)", m, Material);
            generatedMesh.gameObject.AddComponent <BoxCollider>();
            GeneratedMeshes.Add(generatedMesh);
        }

        if (DestroyOriginalMesh)
        {
            Destroy(meshToCut.gameObject);
            GeneratedMeshes.RemoveAt(0);
        }
    }
Beispiel #4
0
    /**
     * Slice a GameObject with a plane and return the two new GameObject.
     * If destroyGameObject is true and the slice is successful then the original game object is destroyed.
     */
    public static List <GameObject> Slice(GameObject original, Plane plane, bool destroyGameObject = true)
    {
        List <GameObject> slicedParts = new List <GameObject>();

        MeshFilter originalMeshFilter = original.GetComponent <MeshFilter>();

        if (originalMeshFilter)
        {
            MeshSlicer meshSlicer = new MeshSlicer(originalMeshFilter.sharedMesh, plane);
            if (meshSlicer.Slice())
            {
                // We want the upper mesh to "spawn" upper than the lower mesh on the plane.normal axis
                bool isPlaneDirectionGood = Vector3.Dot(plane.normal, meshSlicer.offsetUpper) >= 0f;

                GameObject upperPart = new GameObject(original.name + "_1");
                GameObject lowerPart = new GameObject(original.name + "_0");

                // We copy the main properties of the original transform to the two new objects
                upperPart.transform.parent = original.transform.parent;
                lowerPart.transform.parent = original.transform.parent;

                // Offset the position so that the new meshes looks still in place
                upperPart.transform.localPosition = original.transform.localPosition + Quaternion.Euler(original.transform.eulerAngles) * (Vector3.Scale(meshSlicer.offsetUpper, original.transform.localScale) * ((isPlaneDirectionGood) ? 1 : -1));
                lowerPart.transform.localPosition = original.transform.localPosition + Quaternion.Euler(original.transform.eulerAngles) * (Vector3.Scale(meshSlicer.offsetLower, original.transform.localScale) * ((isPlaneDirectionGood) ? 1 : -1));

                upperPart.transform.localRotation = original.transform.localRotation;
                lowerPart.transform.localRotation = original.transform.localRotation;

                upperPart.transform.localScale = original.transform.localScale;
                lowerPart.transform.localScale = original.transform.localScale;

                // Then we assign the meshes
                MeshFilter upperMeshFilter = upperPart.AddComponent <MeshFilter>();
                MeshFilter lowerMeshFilter = lowerPart.AddComponent <MeshFilter>();
                upperMeshFilter.mesh = meshSlicer.upperMesh;
                lowerMeshFilter.mesh = meshSlicer.lowerMesh;

                MeshRenderer originalMeshRenderer = original.GetComponent <MeshRenderer>();

                if (originalMeshRenderer)
                {
                    MeshRenderer upperMeshRenderer = upperPart.AddComponent <MeshRenderer>();
                    MeshRenderer lowerMeshRenderer = lowerPart.AddComponent <MeshRenderer>();
                    upperMeshRenderer.materials = originalMeshRenderer.sharedMaterials;
                    lowerMeshRenderer.materials = originalMeshRenderer.sharedMaterials;
                }

                slicedParts.Add(lowerPart);
                slicedParts.Add(upperPart);

                if (destroyGameObject)
                {
                    UnityEngine.Object.Destroy(original);
                }
            }
        }

        return(slicedParts);
    }
    private void OnGUI()
    {
        if (GUILayout.Button("slice mesh", GUILayout.Width(100), GUILayout.Height(60)))
        {
            Plane slicerPlane = new Plane(slicerNormal, slicerDistance);

            Mesh     targetMesh       = null;
            Material originalMaterial = null;

            MeshFilter meshFilter = TargetGameobject.GetComponentInChildren <MeshFilter>();
            if (meshFilter != null)
            {
                targetMesh = meshFilter.mesh;
            }
            else
            {
                SkinnedMeshRenderer skinMeshRenderer = TargetGameobject.GetComponentInChildren <SkinnedMeshRenderer>();
                if (skinMeshRenderer != null)
                {
                    targetMesh       = skinMeshRenderer.sharedMesh;
                    originalMaterial = skinMeshRenderer.material;
                }
            }

            if (!targetMesh)
            {
                Debug.LogError("target mesh is null");
                return;
            }

            if (!originalMaterial)
            {
                MeshRenderer meshRenderer = TargetGameobject.GetComponentInChildren <MeshRenderer>();
                if (meshRenderer)
                {
                    originalMaterial = meshRenderer.material;
                }
            }
            m_meshSlicer = new MeshSlicer(targetMesh, slicerPlane);
            m_meshSlicer.Slice(IncludeIntersection, IncludeOppsiteSide);

            if (!SlicedUpperMaterial)
            {
                SlicedUpperMaterial = originalMaterial;
            }

            m_meshSlicer.RenderSlicedGameObject(SlicedUpperMaterial, SlicedUnderMaterial, SlicedUpperIntersectionMaterial, SlicedUnderIntersectionMaterial, TargetGameobject.name);

            if (RemainOriginGameObject)
            {
                TargetGameobject.SetActive(false);
            }
            else
            {
                GameObject.Destroy(TargetGameobject);
            }
        }
    }
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        if (GUILayout.Button("Slice"))
        {
            MeshSlicer slicer = target as MeshSlicer;
            slicer.Slice(slicer.entity);
        }
    }
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        MeshSlicer slicer = (MeshSlicer)target;

        if (GUILayout.Button("Slice") && Application.isPlaying)
        {
            slicer.Slice();
        }
    }
Beispiel #8
0
    /// <summary>
    /// 获取贴花的模型
    /// </summary>
    /// <param name="targetMesh"></param>
    /// <param name="targetMeshLocalToWorldMatrix"></param>
    /// <param name="position"></param>
    /// <param name="decalSize"></param>
    /// <param name="rotationEular"></param>
    /// <returns></returns>
    /// todo: 可以根据点基位置估算一个切割顺序,优化,主要基于动态模型切割算法
    public Mesh GetDecalMesh(Mesh targetMesh, Vector3 position, Vector3 decalSize, Vector3 rotationEular, Matrix4x4 projectorCoord)
    {
        Mesh decalMesh = targetMesh;

        //back
        Plane      projectorEdgePlane = GetDecalProjectorEdgePlane(position, rotationEular, decalSize.z, projectorCoord.GetRow(2));
        MeshSlicer slicer             = new MeshSlicer(decalMesh, projectorEdgePlane);

        SlicedMesh slicedMesh = slicer.Slice(false, false);

        if (slicedMesh.UpperMesh == null)
        {
            return(null);
        }

        //left
        projectorEdgePlane = GetDecalProjectorEdgePlane(position, rotationEular, decalSize.x, -projectorCoord.GetRow(0));
        slicedMesh         = MeshSlicer.SliceTriangleList(slicedMesh.UpperMeshTriangleList, projectorEdgePlane, false, false);
        if (slicedMesh == null)
        {
            return(null);
        }

        //right
        projectorEdgePlane = GetDecalProjectorEdgePlane(position, rotationEular, decalSize.x, projectorCoord.GetRow(0));
        slicedMesh         = MeshSlicer.SliceTriangleList(slicedMesh.UpperMeshTriangleList, projectorEdgePlane, false, false);
        if (slicedMesh == null)
        {
            return(null);
        }


        //up
        projectorEdgePlane = GetDecalProjectorEdgePlane(position, rotationEular, decalSize.y, projectorCoord.GetRow(1));
        slicer             = new MeshSlicer(slicedMesh.UpperMesh, projectorEdgePlane);
        slicedMesh         = slicer.Slice(false, false);
        if (slicedMesh.UpperMesh == null)
        {
            return(null);
        }

        //down
        projectorEdgePlane = GetDecalProjectorEdgePlane(position, rotationEular, decalSize.y, -projectorCoord.GetRow(1));
        slicedMesh         = MeshSlicer.SliceTriangleList(slicedMesh.UpperMeshTriangleList, projectorEdgePlane, false, false);
        if (slicedMesh == null)
        {
            return(null);
        }

        return(slicedMesh.UpperMesh);
    }
Beispiel #9
0
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hit;
            Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit, 1000000))
            {
                if (hit.transform.GetComponent <MeshRenderer>() != null)
                {
                    Position = hit.transform.position;

                    Material1       = new Material(Material1);
                    Material2       = new Material(Material2);
                    Material1.color = Random.ColorHSV();
                    Material2.color = Random.ColorHSV();

                    var mesh     = hit.transform.gameObject.GetComponent <MeshFilter>().mesh;
                    var material = hit.transform.gameObject.GetComponent <MeshRenderer>().material;

                    var slicedMesh = MeshSlicer.Slice(mesh, hit.transform.InverseTransformDirection(transform.up), hit.transform.InverseTransformPoint(hit.point));

                    var go1 = new GameObject();
                    go1.transform.position = hit.transform.position;
                    go1.transform.rotation = hit.transform.rotation;
                    go1.AddComponent <MeshFilter>().mesh         = slicedMesh.Mesh1;
                    go1.AddComponent <MeshCollider>().sharedMesh = slicedMesh.Mesh1;
                    go1.AddComponent <MeshRenderer>().material   = Material1;
                    go1.GetComponent <MeshCollider>().convex     = true;
                    //go1.AddComponent<Rigidbody>();

                    var go2 = new GameObject();
                    go2.transform.position = hit.transform.position;
                    go2.transform.rotation = hit.transform.rotation;
                    go2.AddComponent <MeshFilter>().mesh         = slicedMesh.Mesh2;
                    go2.AddComponent <MeshCollider>().sharedMesh = slicedMesh.Mesh2;
                    go2.AddComponent <MeshRenderer>().material   = Material2;
                    go2.GetComponent <MeshCollider>().convex     = true;
                    //go2.AddComponent<Rigidbody>();

                    Destroy(hit.transform.gameObject);
                }
            }
        }
    }
Beispiel #10
0
    /**
     * Slice a gameobject according to a list of cutting plane.
     * We keep the geometry that falls below the cutting plane.
     */
    public static GameObject CellSlice(GameObject original, List <Plane> cuttingPlanes, bool destroyGameObject = true)
    {
        MeshFilter originalMeshFilter = original.GetComponent <MeshFilter>();
        GameObject cell = null;

        if (originalMeshFilter)
        {
            Mesh finalMesh = originalMeshFilter.sharedMesh;
            cell = new GameObject(original.name + "_cell");

            // We copy the main properties of the original transform to the cell
            cell.transform.parent        = original.transform.parent;
            cell.transform.localPosition = original.transform.localPosition;
            cell.transform.localRotation = original.transform.localRotation;
            cell.transform.localScale    = original.transform.localScale;

            Vector3 planeOffset = Vector3.zero;
            for (int i = 0; i < cuttingPlanes.Count; ++i)
            {
                MeshSlicer meshSlicer = new MeshSlicer(finalMesh, cuttingPlanes[i]);
                if (meshSlicer.Slice())
                {
                    // Offset the position so that the new mesh looks still in place
                    cell.transform.localPosition = cell.transform.localPosition + Quaternion.Euler(cell.transform.eulerAngles) *
                                                   (Vector3.Scale(meshSlicer.offsetLower, cell.transform.localScale));

                    planeOffset -= meshSlicer.offsetLower;

                    if (i != cuttingPlanes.Count - 1)
                    {
                        cuttingPlanes[i + 1].Move(planeOffset);
                    }
                    finalMesh = meshSlicer.lowerMesh;
                }
                else
                {
                    if (i != cuttingPlanes.Count - 1)
                    {
                        cuttingPlanes[i + 1].Move(planeOffset);
                    }
                }
            }

            // Then we assign the meshes
            MeshFilter cellMeshFilter = cell.AddComponent <MeshFilter>();
            cellMeshFilter.mesh = finalMesh;

            MeshRenderer originalMeshRenderer = original.GetComponent <MeshRenderer>();

            if (originalMeshRenderer)
            {
                MeshRenderer cellMeshRenderer = cell.AddComponent <MeshRenderer>();
                cellMeshRenderer.materials = originalMeshRenderer.sharedMaterials;
            }

            if (destroyGameObject)
            {
                UnityEngine.Object.Destroy(original);
            }
        }

        return(cell);
    }