public static void SliceHorz(GameObject sourceGameObject, GameObject clipperPlane, Mesh targetMesh, Mesh[] slicedMeshes, int idx, int slices, Bounds bounds, bool cap) { Vector3 minBounds = bounds.min; Vector3 maxBounds = bounds.max; Mesh cuttingMesh = targetMesh; Mesh[] slicedHorzMeshes = new Mesh[slices]; for (int i = 0; i < slices; i++) { slicedHorzMeshes[i] = new Mesh(); } clipperPlane.transform.rotation = Quaternion.Euler(0, 0, 90); for (int i = 0; i < slices - 1; i++) { clipperPlane.transform.position = new Vector3(Mathf.Lerp(minBounds.x, maxBounds.x, (float)(i + 1) / (float)slices), 0, 0); Mesh[] horzClipMeshes = new Mesh[2]; horzClipMeshes[0] = slicedHorzMeshes[i]; horzClipMeshes[1] = slicedHorzMeshes[i + 1]; if (MeshSlicer.CutTriangleMesh(horzClipMeshes, cuttingMesh, new Plane(clipperPlane.transform.up, clipperPlane.transform.position), sourceGameObject.transform, clipperPlane.transform, cap)) { cuttingMesh = horzClipMeshes[1]; } } for (int i = 0; i < slices; i++) { slicedMeshes[idx + i].Clear(); slicedMeshes[idx + i] = slicedHorzMeshes[i]; } }
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); } } }
// Detect & slice "sliceable" GameObjects whose bounding box intersects slicing plane private void Slice(MeshSlicer.CustomPlane plane) { SliceableObject[] sliceableTargets = (SliceableObject[])FindObjectsOfType(typeof(SliceableObject)); bool isSliced = false; foreach (SliceableObject sliceableTarget in sliceableTargets) { GameObject target = sliceableTarget.gameObject; if (plane.HitTest(target)) { if (target.GetComponent <SliceableObject>().isConvex) { MeshSlicer.SliceMesh(target, plane, true); //audioSource.PlayOneShot(sliceableTarget.sliceSound, 1.0f); isSliced = true; } else { MeshSlicer.SliceMesh(target, plane, false); //audioSource.PlayOneShot(sliceableTarget.sliceSound, 1.0f); isSliced = true; } } } if (!isSliced) { audioSource.PlayOneShot(sliceMissSound, 1.0f); } }
/// <summary> /// z1 > z2 /// </summary> /// <param name="z1"></param> /// <param name="z2"></param> /// <returns></returns> public List <Vector3> Intersect2Layers(float z1, float z2) { List <Vector3> result = null; var points = new List <Vector3>() { new Vector3(0, 0, z1), new Vector3(1, 0, z1), new Vector3(0, 1, z1) }; Mesh hat1; MeshSlicer.SliceMeshByPlane(meshFilter.mesh, points[0], points[1], points[2], out hat1); points = new List <Vector3>() { new Vector3(0, 0, z2), new Vector3(1, 0, z2), new Vector3(0, 1, z2) }; Mesh hat2; MeshSlicer.SliceMeshByPlane(meshFilter.mesh, points[0], points[1], points[2], out hat2); var firstList = new List <Vector3>(hat1.vertices); firstList.RemoveAt(firstList.Count - 1); var secondList = new List <Vector3>(hat2.vertices); secondList.RemoveAt(secondList.Count - 1); return(PolygonIntersector.IntersectPolygons(firstList, secondList)); }
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); } }
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); } } }
/** * 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); } }
private void Update() { var cuttingPlane = new Plane(_planeTrans.up, _planeTrans.position); for (int i = 0; i < meshes.Length; i++) { MeshSlicer.CutTriangleMeshOneSide(_outputMesh[i], meshes[i].mesh, cuttingPlane, meshes[i].transform, _planeTrans, false, true); Graphics.DrawMesh(_outputMesh[i], meshes[i].transform.localToWorldMatrix, meshes[i].renderer.material, 0); } }
public void ResetSlicingPlanePosition(MeshSlicer meshSlicer, bool toTop) { if (meshSlicer) { if (meshSlicer.slicingPlane) { meshSlicer.slicingPlane.ResetPlanePosition(toTop); } } }
public override void OnInspectorGUI() { DrawDefaultInspector(); MeshSlicer slicer = (MeshSlicer)target; if (GUILayout.Button("Slice") && Application.isPlaying) { slicer.Slice(); } }
// TRIGGER EXIT void TriggerExit(Collider coll) { if (On_Trigger_Exit != null) { On_Trigger_Exit.Invoke(coll); } if (coll.GetComponent <Laser_Collider> () != null) { if (hit_lens != null) { hit_lens.enabled = false; } } if (slicing) { if (slice_layer == (slice_layer | (1 << coll.gameObject.layer))) { coll_end_point_1 = coll.ClosestPointOnBounds(laser_trans.position); coll_end_point_2 = coll.ClosestPointOnBounds(origin.position); Plane plane = new Plane(coll_start_point, coll_end_point_1, coll_end_point_2); Vector3 center = (coll_start_point + coll_end_point_1 + coll_end_point_2) / 3; Material mat = sliced_material; if (mat == null) { mat = coll.GetComponent <Renderer> ().material; } GameObject[] gos = MeshSlicer.Cut(coll.gameObject, center, plane.normal, mat); Destroy(coll); gos [1].gameObject.layer = coll.gameObject.layer; if (!gos [1].GetComponent <Rigidbody> ()) { gos [1].AddComponent <Rigidbody> (); } MeshCollider mc1 = gos [1].AddComponent <MeshCollider> (); mc1.convex = true; gos [0].gameObject.layer = coll.gameObject.layer; if (!gos [0].GetComponent <Rigidbody> ()) { gos [0].AddComponent <Rigidbody> (); } MeshCollider mc2 = gos [0].AddComponent <MeshCollider> (); mc2.convex = true; } } }
/// <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); } } } }
private void Update() { var cuttingPlane = new Plane(_planeTrans.up, _planeTrans.position); for (int i = 0; i < meshes.Length; i++) { if (_outputMesh[i] == null) { UnityEngine.Debug.Log("_outputMesh"); } if (meshes[i] == null) { UnityEngine.Debug.Log("meshes"); } MeshSlicer.CutTriangleMeshOneSide(_outputMesh[i], meshes[i].mesh, cuttingPlane, meshes[i].transform, _planeTrans, false, true); Graphics.DrawMesh(_outputMesh[i], meshes[i].transform.localToWorldMatrix, meshes[i].GetComponent <Renderer>().material, 0); } }
/// <summary> /// Defines which meshes must be cut /// </summary> /// <param name="cutPlane"></param> private void ImplementCut(Plane cutPlane) { SwipeEffect(); List <RawMeshData> res = new List <RawMeshData>(); for (int i = _objectsOnScene.Count - 1; i >= 0; i--) { res = MeshSlicer.SliceMesh(cutPlane, _objectsOnScene[i]); if (res.Count > 0) { Destroy(_objectsOnScene[i].gameObject); _objectsOnScene.RemoveAt(i); } foreach (var slice in res) { InstantiateSlice(slice); } } }
// Detect & slice "sliceable" GameObjects whose bounding box intersects slicing plane private void Slice(MeshSlicer.CustomPlane plane) { SliceableObject[] sliceableTargets = (SliceableObject[])FindObjectsOfType( typeof(SliceableObject) ); bool isSliced = false; foreach(SliceableObject sliceableTarget in sliceableTargets) { GameObject target = sliceableTarget.gameObject; if(plane.HitTest(target)) { if(target.GetComponent<SliceableObject>().isConvex) { MeshSlicer.SliceMesh(target, plane, true); //audioSource.PlayOneShot(sliceableTarget.sliceSound, 1.0f); isSliced = true; } else { MeshSlicer.SliceMesh(target, plane, false); //audioSource.PlayOneShot(sliceableTarget.sliceSound, 1.0f); isSliced = true; } } } if(!isSliced) { audioSource.PlayOneShot(sliceMissSound, 1.0f); } }
public static Mesh[] ChunkMesh(GameObject sourceGameObject, Mesh[] slicedMeshes, int verticalSlices, int horizontalSlices, bool cap) { Mesh sourceMesh = sourceGameObject.GetComponent <MeshFilter>().mesh; Bounds bounds = sourceGameObject.renderer.bounds; Vector3 minBounds = bounds.min; Vector3 maxBounds = bounds.max; GameObject clipperPlane = GameObject.CreatePrimitive(PrimitiveType.Plane); if (verticalSlices == 1) { MeshSlicer.SliceHorz(sourceGameObject, clipperPlane, sourceMesh, slicedMeshes, 0, horizontalSlices, bounds, cap); } else { for (int j = 0; j < verticalSlices - 1; j++) { clipperPlane.transform.rotation = Quaternion.Euler(0, 0, 0); clipperPlane.transform.position = new Vector3(0, Mathf.Lerp(maxBounds.y, minBounds.y, (float)(j + 1) / (float)verticalSlices), 0); Mesh[] vertClipMeshes = new Mesh[2]; vertClipMeshes[0] = slicedMeshes[j * horizontalSlices]; vertClipMeshes[1] = slicedMeshes[(j + 1) * horizontalSlices]; MeshSlicer.CutTriangleMesh(vertClipMeshes, sourceMesh, new Plane(clipperPlane.transform.up, clipperPlane.transform.position), sourceGameObject.transform, clipperPlane.transform, cap); MeshSlicer.SliceHorz(sourceGameObject, clipperPlane, slicedMeshes[j * horizontalSlices], slicedMeshes, j * horizontalSlices, horizontalSlices, bounds, cap); sourceMesh = vertClipMeshes[1]; } MeshSlicer.SliceHorz(sourceGameObject, clipperPlane, slicedMeshes[(verticalSlices - 1) * horizontalSlices], slicedMeshes, (verticalSlices - 1) * horizontalSlices, horizontalSlices, bounds, cap); } Destroy(clipperPlane); return(slicedMeshes); }
public static Mesh[] Slice(Mesh original, Vector3 planePos, Vector3 planeNormal) { MeshSlicer slicer = new MeshSlicer(original, planePos, planeNormal); return(slicer.DoSlice()); }
/// <summary> /// This method slices the mesh of the Gameobject by the specified plane. /// </summary> /// <param name="plane">The plane which shall seperate the objects mesh</param> public void SliceByPlane(Plane plane) { uvMapper = uvMapperObject.GetComponent<UVMapper>(); if (uvMapper != null) { MeshSlicer slicer = new MeshSlicer(uvMapper); MeshFilter meshFilter = this.GetComponent<MeshFilter>(); Mesh mesh = meshFilter.mesh; Mesh[] slicedMeshes = slicer.SliceByPlane(mesh, plane, this.transform); meshFilter.mesh.Clear(); if (slicedMeshes[0].vertices.Length > 0 && slicedMeshes[0].triangles.Length > 0) { //Setting the mesh of the gameobject which shall be splitted(Fracture1). meshFilter.mesh = slicedMeshes[0]; if (slicedMeshes[1].vertices.Length > 0 && slicedMeshes[1].triangles.Length > 0) { // copying the the gameobject which should be drestroyed(source) GameObject copy = (GameObject)GameObject.Instantiate(this.gameObject); // setting the mesh of the copy MeshFilter meshFilter2 = copy.GetComponent<MeshFilter>(); meshFilter2.mesh.Clear(); meshFilter2.mesh = slicedMeshes[1]; //Updating the collider of the copied gameobject copy.GetComponent<MeshCollider>().sharedMesh = meshFilter2.mesh; } } else if (slicedMeshes[1].vertices.Length > 0 && slicedMeshes[1].triangles.Length > 0) { meshFilter.mesh = slicedMeshes[1]; } //Updating the collider of this gameobject DestroyImmediate(this.GetComponent<MeshCollider>()); MeshCollider collider1 = this.gameObject.AddComponent<MeshCollider>(); collider1.convex = true; } }
public void OnSliceButtonClick() { if (state == LayerBankState.empty) { return; } if (state == LayerBankState.drawSlices) { ToggleSliceMeshComponent(false); ToggleMainMeshComponents(true); state = LayerBankState.drawMainMesh; return; } if (state == LayerBankState.drawMainMesh) { hats = new List <Mesh>(); state = LayerBankState.drawSlices; ToggleMainMeshComponents(false); ToggleSliceMeshComponent(true); var zmin = layers[0][0].z; var zmax = layers[layers.Count - 1][0].z; int slicesNum; if (!int.TryParse(slicesCount.text, out slicesNum)) { slicesNum = 5; } List <Vector3> points; if (Drag_n_drop.lastHitPlane != null) { points = Drag_n_drop.lastHitPlane; } else { points = new List <Vector3>() { new Vector3(0, 0, zmin), new Vector3(1, 0, zmin), new Vector3(0, 1, zmin) }; } var centr = LayerHelper.CalcCenterPoint(meshFilter.mesh); var plane = new Plane(points[0], points[1], points[2]); if (Vector3.Magnitude(plane.normal + (centr - points[0])) < Vector3.Magnitude(centr - points[0])) { var temp = points[0]; points[0] = points[1]; points[1] = temp; } plane = new Plane(points[0], points[1], points[2]); float size = 0; foreach (var i in meshFilter.mesh.vertices) { size = Mathf.Max(size, plane.GetDistanceToPoint(i)); } slices = MeshSlicer.SliceInPeaces(slicesNum, meshFilter.mesh, size, points, out hats); lastSliceVector = plane.normal.normalized; hats.Add(upperBound.mesh); hats.Insert(0, downBound.mesh); SetSlice(0); //StartCoroutine(DrawSlices(slices, hats)); } }
/// <summary> /// This method destroys the mesh of an gameobject! /// This algorithm works by splitting the mesh into smaller objects by slicing the gameobject /// by different planes, which will be generated randomly, but all Planes will intersect at one /// point specified by the raycastHit. /// TODO: Refactoring! /// </summary> /// <param name="raycastHit">The center point of the destruction</param> /// <param name="explosionForce">The force of the explosion</param> /// <param name="explosionRadius">The distance from the explosion center</param> /// <returns>a list of all destruchtion-fragments</returns> public List<Destructor> DestroyGeometry(RaycastHit raycastHit, float explosionForce, float explosionRadius) { List<Destructor> destructionObjects = new List<Destructor>(); Vector3 hitpoint = raycastHit.point; Vector3 n; Plane randomPlane; Mesh startMesh = this.GetComponent<MeshFilter>().mesh; List<Mesh> destructionParts = new List<Mesh>(); List<Mesh> currentDestructionParts = new List<Mesh>(); destructionParts.Add(startMesh); uvMapper = uvMapperObject.GetComponent<UVMapper>(); if (uvMapper != null) { MeshSlicer slicer = new MeshSlicer(uvMapper); //Iterating over all jet existing mesh-fractures. //The algorithm uses old created fratures to create new. for (int i = 0; i < fractureCount; i++) { // A random vetor which is used to generate a new random slicing plane. n = GenerateRandomVector(); randomPlane = new Plane(n, hitpoint); // Iterating over all yet existing destruction parts and slicing them by the plane foreach (Mesh mesh in destructionParts) { currentDestructionParts.AddRange(slicer.SliceByPlane(mesh, randomPlane, this.transform)); } // the new created destruction parts are the base for the next iteration destructionParts = currentDestructionParts; currentDestructionParts = new List<Mesh>(); } GameObject destructedObject; MeshFilter destructedObjectMeshFilter; MeshRenderer destructedObjectMeshRenderer; Mesh destructedObjectMesh; Vector3 meshMidPoint; Mesh currentMesh; Vector3 newMeshMidpoint; // Creating new Gameobjects by using the meshes generated in the previous step. foreach (Mesh mesh in destructionParts) { if (mesh.vertices.Length > 0 && mesh.triangles.Length > 0) { // Initializing a new gameobject and bringing its pivot to the center of the objects mesh. meshMidPoint = transform.TransformPoint(MeshComponents.GetVerticesMidpoint(mesh.vertices)); destructedObject = (GameObject)GameObject.Instantiate(this.gameObject, meshMidPoint, Quaternion.identity); destructedObjectMeshFilter = destructedObject.GetComponent<MeshFilter>(); currentMesh = mesh.Translate(DevideVectors(destructedObjectMeshFilter.transform.InverseTransformDirection(transform.position - destructedObject.transform.position), destructedObject.transform.lossyScale)); newMeshMidpoint = transform.TransformPoint(MeshComponents.GetVerticesMidpoint(currentMesh.vertices)); // Adding the generated mesh-geometrie to the new created gameobject destructedObjectMesh = destructedObjectMeshFilter.mesh; destructedObjectMeshRenderer = destructedObject.GetComponent<MeshRenderer>(); destructedObjectMesh.Clear(); destructedObjectMeshFilter.mesh = currentMesh; //Updating the collider of the gameobject ChangeColliderToMeshCollider(destructedObject); destructedObject.GetComponent<MeshCollider>().sharedMesh = currentMesh; //Adding some explosiontforce to the gameobject foe vfx destructedObject.GetComponent<Rigidbody>().AddExplosionForce(explosionForce, raycastHit.point, explosionRadius); destructionObjects.Add(destructedObject.GetComponent<Destructor>()); } } //After all new fractureparts are generated -> destroy the source. DestroyImmediate(this.gameObject); } return destructionObjects; }
/** * 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); }
private void Awake() { _input = new InputManager(); _slicer = new MeshSlicer(); }