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); } } }
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); } }
/** * 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(); } }
/// <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); }
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); } } } }
/** * 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); }