private void CreateTravelerClone(PortalTraveler portalTraveler, bool enteredFromBack) { lstPortalTravelers.Add(portalTraveler); TransformToTarget(portalTraveler.transform, out Vector3 newPos, out Quaternion newRot); PortalTraveler travelerCopy = Instantiate(portalTraveler, newPos, newRot); travelerCopy.enabled = false; SimpleMove simpleMoveComponent = travelerCopy.GetComponent <SimpleMove>(); if (simpleMoveComponent) { simpleMoveComponent.enabled = false; } Sliceable sliceable = portalTraveler.GetComponent <Sliceable>(); sliceable.SlicePosition = transform.position; sliceable.SliceNormal = transform.forward; sliceable.IsSliceable = true; sliceable.Flip = !enteredFromBack; sliceable.UpdateMaterialSlice(); if (target) { sliceable = travelerCopy.GetComponent <Sliceable>(); sliceable.SlicePosition = target.transform.position; sliceable.SliceNormal = target.transform.forward; sliceable.IsSliceable = true; sliceable.Flip = enteredFromBack; sliceable.UpdateMaterialSlice(); } travelerCopies.Add(portalTraveler, travelerCopy.gameObject); }
public void OnTriggerExit(Collider other) { PortalTraveler portalTraveler = other.GetComponent <PortalTraveler>(); if (portalTraveler != null) { if (other.CompareTag("Player")) { playerTraveler = null; var originalPosition = new Vector3(0, portalDisplay.transform.localPosition.y, 0); PortalAdjustment(originalPosition, originalPortalScale); target.PortalAdjustment(originalPosition, originalPortalScale); } else { Sliceable sliceable = portalTraveler.GetComponent <Sliceable>(); sliceable.IsSliceable = false; sliceable.UpdateMaterialSlice(); TransformToTarget(portalTraveler.transform); lstPortalTravelers.Remove(portalTraveler); DestroyTravelerCopy(portalTraveler); travelerCopies.Remove(portalTraveler); } } }
//Add different components to the game objects depending on if they're staying or not void AddComponent(GameObject obj, bool stay) { obj.gameObject.layer = 8; obj.AddComponent <BoxCollider>(); obj.GetComponent <BoxCollider>().size = new Vector3(obj.GetComponent <BoxCollider>().size.x, 0, obj.GetComponent <BoxCollider>().size.z); obj.GetComponent <BoxCollider>().center = new Vector3(obj.GetComponent <BoxCollider>().center.x, 0, obj.GetComponent <BoxCollider>().center.z); BoxCollider bcol = obj.AddComponent <BoxCollider>(); bcol.isTrigger = true; if (!stay) { obj.AddComponent <Rigidbody>(); obj.GetComponent <Rigidbody>().interpolation = RigidbodyInterpolation.Interpolate; obj.GetComponent <Rigidbody>().AddExplosionForce(100, obj.transform.position, 20); Destroy(obj, 3f); } else { obj.AddComponent <Sliceable>(); Sliceable temp = obj.GetComponent <Sliceable>(); temp.SetMaster(this); temp.SetGameStarted(true); _gm.SetSliceable(temp); } }
// Use this for initialization void Start() { if (_instance != null) { Debug.LogWarning("There may be multiple TurboSlice components in scene " + Application.loadedLevelName + ". Please review this!"); } _instance = this; if (meshCaching) { meshCaches = new Dictionary <Mesh, MeshCache>(); foreach (GameObject go in preload) { Sliceable s = ensureSliceable(go); MeshCache c = cacheFromGameObject(s, false); c.wasPreloaded = true; MeshFilter filter = getMeshFilter(s); if (filter == null) { Mesh m = filter.sharedMesh; meshCaches[m] = c; } else { Debug.LogWarning("Turbo Slicer cannot preload object '" + go.name + "'; cannot find mesh filter."); } } } }
/// <summary> /// Slice the object by the plane /// </summary> /// <param name="plane"></param> /// <param name="objectToCut"></param> /// <returns></returns> public static GameObject[] Slice(Plane plane, GameObject objectToCut) { //Get the current mesh and its verts and tris Mesh mesh = objectToCut.GetComponent <MeshFilter>().mesh; var a = mesh.GetSubMesh(0); Sliceable sliceable = objectToCut.GetComponent <Sliceable>(); if (sliceable == null) { throw new NotSupportedException("Cannot slice non sliceable object, add the sliceable script to the object or inherit from sliceable to support slicing"); } //Create left and right slice of hollow object SlicesMetadata slicesMeta = new SlicesMetadata(plane, mesh, sliceable.IsSolid, sliceable.ReverseWireTriangles, sliceable.ShareVertices, sliceable.SmoothVertices); GameObject positiveObject = CreateMeshGameObject(objectToCut); positiveObject.name = string.Format("{0}_positive", objectToCut.name); GameObject negativeObject = CreateMeshGameObject(objectToCut); negativeObject.name = string.Format("{0}_negative", objectToCut.name); var positiveSideMeshData = slicesMeta.PositiveSideMesh; var negativeSideMeshData = slicesMeta.NegativeSideMesh; positiveObject.GetComponent <MeshFilter>().mesh = positiveSideMeshData; negativeObject.GetComponent <MeshFilter>().mesh = negativeSideMeshData; SetupCollidersAndRigidBodys(ref positiveObject, positiveSideMeshData, sliceable.UseGravity); SetupCollidersAndRigidBodys(ref negativeObject, negativeSideMeshData, sliceable.UseGravity); return(new GameObject[] { positiveObject, negativeObject }); }
private void SliceThis(Sliceable otherSliceable) { if (otherSliceable != null && !justSliced.Contains(otherSliceable) && !pendingSlices.Contains(otherSliceable)) { pendingSlices.Add(otherSliceable); } }
public GameObject[] shatter(GameObject go, int steps) { Sliceable priorSliceable = go.GetComponent <Sliceable>(); List <GameObject> l = new List <GameObject>(); l.Add(go); List <GameObject> l2 = l; for (int i = 0; i < steps; i++) { l2 = new List <GameObject>(l.Count * 2); Vector4 shatterPlane = (Vector4)Random.insideUnitSphere; foreach (GameObject go2 in l) { l2.AddRange(_splitByPlane(go2, shatterPlane, true, false)); } l = l2; } GameObject[] results = l2.ToArray(); if (priorSliceable != null) { priorSliceable.handleSlice(results); } return(results); }
/// <summary> /// Creates the default mesh game object. /// </summary> /// <param name="originalObject">The original object.</param> /// <returns></returns> private static GameObject CreateMeshGameObject(GameObject originalObject) { var originalMaterial = originalObject.GetComponent <MeshRenderer>().materials; GameObject meshGameObject = new GameObject(); Sliceable originalSliceable = originalObject.GetComponent <Sliceable>(); meshGameObject.AddComponent <MeshFilter>(); meshGameObject.AddComponent <MeshRenderer>(); Sliceable sliceable = meshGameObject.AddComponent <Sliceable>(); sliceable.IsSolid = originalSliceable.IsSolid; sliceable.ReverseWireTriangles = originalSliceable.ReverseWireTriangles; sliceable.UseGravity = originalSliceable.UseGravity; meshGameObject.GetComponent <MeshRenderer>().materials = originalMaterial; meshGameObject.transform.localScale = originalObject.transform.localScale; meshGameObject.transform.rotation = originalObject.transform.rotation; meshGameObject.transform.position = originalObject.transform.position; meshGameObject.tag = originalObject.tag; return(meshGameObject); }
private MeshCache cacheFromGameObject(Sliceable sliceable, bool includeRoomForGrowth) { Renderer renderer = getMeshRenderer(sliceable); Mesh m = getMesh(sliceable); int initialCapacity = includeRoomForGrowth ? Mathf.RoundToInt((float)m.vertexCount * factorOfSafetyGeometry) : m.vertexCount; MeshCache c = new MeshCache(); c.vertices = new TurboList <Vector3>(initialCapacity); if (sliceable.channelNormals) { c.normals = new TurboList <Vector3>(initialCapacity); } c.coords = new TurboList <Vector2>(initialCapacity); if (sliceable.channelUV2) { c.coords2 = new TurboList <Vector2>(initialCapacity); } c.indices = new int[m.subMeshCount][]; for (int i = 0; i < m.subMeshCount; i++) { c.indices[i] = m.GetTriangles(i); } c.vertices.AddArray(m.vertices); if (sliceable.channelNormals) { c.normals.AddArray(m.normals); } c.coords.AddArray(m.uv); if (sliceable.channelUV2) { c.coords2.AddArray(m.uv2); } if (renderer != null) { if (renderer.sharedMaterials == null) { c.mats = new Material[1]; c.mats[0] = renderer.sharedMaterial; } else { c.mats = renderer.sharedMaterials; } } else { Debug.LogError("Object '" + sliceable.name + "' has no renderer"); } return(c); }
private void createResultObjects(GameObject go, Sliceable sliceable, bool forceCloning, Vector4 plane, out GameObject frontObject, out GameObject backObject) { Transform goTransform = go.transform; Dictionary <string, Transform> transformByName; Dictionary <string, bool> frontPresence, backPresence; determinePresence(goTransform, plane, out transformByName, out frontPresence, out backPresence); bool useAlternateForFront, useAlternateForBack; if (sliceable.alternatePrefab == null) { useAlternateForFront = false; useAlternateForBack = false; } else if (sliceable.alwaysCloneFromAlternate) { useAlternateForFront = true; useAlternateForBack = true; } else { useAlternateForFront = sliceable.cloneAlternate(frontPresence); useAlternateForBack = sliceable.cloneAlternate(backPresence); } Object frontSource = useAlternateForFront ? sliceable.alternatePrefab : go; Object backSource = useAlternateForBack ? sliceable.alternatePrefab : go; frontObject = (GameObject)GameObject.Instantiate(frontSource); backObject = (GameObject)GameObject.Instantiate(backSource); handleHierarchy(frontObject.transform, frontPresence, transformByName); handleHierarchy(backObject.transform, backPresence, transformByName); Transform parent = goTransform.parent; Vector3 position = goTransform.localPosition; Vector3 scale = goTransform.localScale; Quaternion rotation = goTransform.localRotation; frontObject.transform.parent = parent; frontObject.transform.localPosition = position; frontObject.transform.localScale = scale; backObject.transform.parent = parent; backObject.transform.localPosition = position; backObject.transform.localScale = scale; frontObject.transform.localRotation = rotation; backObject.transform.localRotation = rotation; frontObject.layer = go.layer; backObject.layer = go.layer; }
private void createResultObjects(GameObject go, Sliceable sliceable, bool forceCloning, Vector4 plane, out GameObject frontObject, out GameObject backObject) { Transform goTransform = go.transform; Dictionary<string,Transform> transformByName; Dictionary<string,bool> frontPresence, backPresence; determinePresence(goTransform, plane, out transformByName, out frontPresence, out backPresence); bool useAlternateForFront, useAlternateForBack; if(sliceable.alternatePrefab == null) { useAlternateForFront = false; useAlternateForBack = false; } else if(sliceable.alwaysCloneFromAlternate) { useAlternateForFront = true; useAlternateForBack = true; } else { useAlternateForFront = sliceable.cloneAlternate(frontPresence); useAlternateForBack = sliceable.cloneAlternate(backPresence); } Object frontSource = useAlternateForFront ? sliceable.alternatePrefab : go; Object backSource = useAlternateForBack ? sliceable.alternatePrefab : go; frontObject = (GameObject) GameObject.Instantiate(frontSource); backObject = (GameObject) GameObject.Instantiate(backSource); handleHierarchy(frontObject.transform, frontPresence, transformByName); handleHierarchy(backObject.transform, backPresence, transformByName); Transform parent = goTransform.parent; Vector3 position = goTransform.localPosition; Vector3 scale = goTransform.localScale; Quaternion rotation = goTransform.localRotation; frontObject.transform.parent = parent; frontObject.transform.localPosition = position; frontObject.transform.localScale = scale; backObject.transform.parent = parent; backObject.transform.localPosition = position; backObject.transform.localScale = scale; frontObject.transform.localRotation = rotation; backObject.transform.localRotation = rotation; frontObject.layer = go.layer; backObject.layer = go.layer; }
private static Renderer getMeshRenderer(Sliceable s) { GameObject holder = getMeshHolder(s); if(holder != null) { return holder.GetComponent(typeof(Renderer)) as Renderer; } else { return null; } }
private static Renderer getMeshRenderer(Sliceable s) { GameObject holder = getMeshHolder(s); if (holder != null) { return(holder.GetComponent(typeof(Renderer)) as Renderer); } else { return(null); } }
private MeshFilter getMeshFilter(Sliceable s) { GameObject holder = getMeshHolder(s); if (holder != null) { return(holder.GetComponent <MeshFilter>()); } else { return(null); } }
private static Sliceable ensureSliceable(GameObject go) { Sliceable sliceable = go.GetComponent <Sliceable>(); if (sliceable == null) { Debug.LogWarning("Turbo Slicer was given an object (" + go.name + ") with no Sliceable; improvising."); sliceable = go.AddComponent <Sliceable>(); sliceable.currentlySliceable = true; sliceable.refreshColliders = true; } return(sliceable); }
private void FixChunk(GameObject chunk, Sliceable victim, Vector3 offsetDirection) { // Resets collider to adjust for current mesh Destroy(chunk.GetComponent <Collider>()); var collider = chunk.AddComponent <MeshCollider>(); collider.convex = true; var sliceable = chunk.GetOrAddComponent <Sliceable>(); var rigidbody = chunk.GetOrAddComponent <Rigidbody>(); var meshFilter = chunk.GetOrAddComponent <MeshFilter>(); sliceable.CutMaterial = victim.CutMaterial; sliceable.MaterialDensity = victim.MaterialDensity; rigidbody.mass = meshFilter.mesh.Volume() * sliceable.MaterialDensity; rigidbody.MovePosition(chunk.transform.position + offsetDirection * .01f); }
public void Cut(Vector3 contact, Sliceable victim, float velocity) { if (velocity > cutVelocityThreshold && previousCuts.Contains(victim)) { previousCuts.Remove(victim); var cutNormal = transform.right; var cuts = MeshCut .Cut(victim.gameObject, contact, cutNormal, victim.CutMaterial) .OrderByDescending(c => c.GetComponent <MeshFilter>().mesh.Volume()) .ToList(); FixChunk(cuts[0], victim, cutNormal); FixChunk(cuts[1], victim, -cutNormal); } }
// Update is called once per frame void LateUpdate() { justSliced.Clear(); if (pendingSlices.Count > 0) { slicePlane[0] = planeDefiner1.position; slicePlane[1] = planeDefiner2.position; slicePlane[2] = planeDefiner3.position; } while (pendingSlices.Count > 0) { Sliceable other = pendingSlices[0]; pendingSlices.RemoveAt(0); if (other != null && other.gameObject != null && other.currentlySliceable) { bool stillSlice = false; if (onlySlicesCategories.Length > 0 && other.category.Length > 0) { foreach (string s in onlySlicesCategories) { stillSlice |= s == other.category; } } else { stillSlice = true; } if (stillSlice) { GameObject[] results = turboSlice.splitByTriangle(other.gameObject, slicePlane, false); if (results[0] != other.gameObject) { GameObject.Destroy(other.gameObject); } justSliced.Add(other); } } } }
private Mesh getMesh(Sliceable s) { GameObject holder = getMeshHolder(s); Renderer renderer = holder.GetComponent <Renderer>(); Mesh mesh = null; if (renderer is MeshRenderer) { mesh = holder.GetComponent <MeshFilter>().mesh; } else if (renderer is SkinnedMeshRenderer) { SkinnedMeshRenderer smr = renderer as SkinnedMeshRenderer; mesh = new Mesh(); smr.BakeMesh(mesh); meshDeletionQueue.Enqueue(mesh); } return(mesh); }
private static GameObject getMeshHolder(Sliceable s) { if (s.explicitlySelectedMeshHolder != null) { return(s.explicitlySelectedMeshHolder); } else { MeshFilter[] allFilters = s.GetComponentsInChildren <MeshFilter>(true); if (allFilters.Length > 0) { return(allFilters[0].gameObject); } else { return(null); } } }
private static void setMesh(Sliceable s, Mesh mesh) { GameObject holder = getMeshHolder(s); Renderer renderer = holder.GetComponent<Renderer>(); MeshFilter filter = null; if(renderer is MeshRenderer) { filter = holder.GetComponent<MeshFilter>(); } else if(renderer is SkinnedMeshRenderer) { holder = s.explicitlySelectedMeshHolder = s.gameObject; Material[] allMats = renderer.sharedMaterials; GameObject.DestroyImmediate(renderer); renderer = holder.AddComponent<MeshRenderer>(); renderer.sharedMaterials = allMats; filter = holder.AddComponent<MeshFilter>(); } if(filter != null) filter.mesh = mesh; }
private static GameObject getMeshHolder(Sliceable s) { if(s.explicitlySelectedMeshHolder != null) { return s.explicitlySelectedMeshHolder; } else { MeshFilter[] allFilters = s.GetComponentsInChildren<MeshFilter>(true); if(allFilters.Length > 0) { return allFilters[0].gameObject; } else { return null; } } }
private static void setMesh(Sliceable s, Mesh mesh) { GameObject holder = getMeshHolder(s); Renderer renderer = holder.GetComponent <Renderer>(); MeshFilter filter = null; if (renderer is MeshRenderer) { filter = holder.GetComponent <MeshFilter>(); } else if (renderer is SkinnedMeshRenderer) { holder = s.explicitlySelectedMeshHolder = s.gameObject; Material[] allMats = renderer.sharedMaterials; GameObject.DestroyImmediate(renderer); renderer = holder.AddComponent <MeshRenderer>(); renderer.sharedMaterials = allMats; filter = holder.AddComponent <MeshFilter>(); } if (filter != null) { filter.mesh = mesh; } }
// Update is called once per frame void Update() { if (Input.GetMouseButton(0)) { Ray cuttingRay = mainCamera.ScreenPointToRay(Input.mousePosition); Vector3 point = cuttingRay.GetPoint(3f); if (!cutting) { cutting = true; startPoint = point; endPoint = point; cameraStartPoint = Input.mousePosition; cameraEndPoint = Input.mousePosition; } else { if (point != startPoint) { foundCut = true; endPoint = point; cameraEndPoint = Input.mousePosition; positions[0] = startPoint; positions[1] = point; lineRenderer.gameObject.SetActive(true); lineRenderer.SetPositions(positions); } else { lineRenderer.gameObject.SetActive(false); foundCut = false; } } } else { if (cutting) { lineRenderer.gameObject.SetActive(false); cutting = false; if (foundCut) { //Vector3 worldNormal = Vector3.Cross(endPoint - startPoint, startPoint - mainCamera.transform.position); foreach (GameObject cutObject in objectsToCut) { // cut the mesh Sliceable sliceable = cutObject.GetComponent <Sliceable>(); if (sliceable) { //sliceable.Slice(startPoint, worldNormal); sliceable.SliceByLine(mainCamera, cameraStartPoint, cameraEndPoint); } } } foundCut = false; } } if (Input.GetMouseButton(1) && !cutting) { Vector3 targetPos = mainCamera.ScreenPointToRay(Input.mousePosition).GetPoint(5f); foreach (GameObject cutObject in objectsToCut) { Rigidbody rb = cutObject.GetComponent <Rigidbody>(); rb.AddForce((targetPos - cutObject.transform.position) * 3f); } } }
private MeshCache cacheFromGameObject(Sliceable sliceable, bool includeRoomForGrowth) { Renderer renderer = getMeshRenderer(sliceable); Mesh m = getMesh(sliceable); int initialCapacity = includeRoomForGrowth ? Mathf.RoundToInt((float) m.vertexCount * factorOfSafetyGeometry) : m.vertexCount; MeshCache c = new MeshCache(); c.vertices = new TurboList<Vector3>(initialCapacity); if(sliceable.channelNormals) c.normals = new TurboList<Vector3>(initialCapacity); c.coords = new TurboList<Vector2>(initialCapacity); if(sliceable.channelUV2) c.coords2 = new TurboList<Vector2>(initialCapacity); c.indices = new int[m.subMeshCount][]; for(int i = 0; i < m.subMeshCount; i++) { c.indices[i] = m.GetTriangles(i); } c.vertices.AddArray(m.vertices); if(sliceable.channelNormals) c.normals.AddArray(m.normals); c.coords.AddArray(m.uv); if(sliceable.channelUV2) c.coords2.AddArray(m.uv2); if(renderer != null) { if(renderer.sharedMaterials == null) { c.mats = new Material[1]; c.mats[0] = renderer.sharedMaterial; } else { c.mats = renderer.sharedMaterials; } } else { Debug.LogError("Object '" + sliceable.name + "' has no renderer"); } return c; }
void OnTriggerEnter(Collider other) { Sliceable otherSliceable = other.GetComponent <Sliceable>(); SliceThis(otherSliceable); }
private MeshRenderer getMeshRenderer(Sliceable s) { GameObject holder = getMeshHolder(s); if(holder != null) { return holder.GetComponent<MeshRenderer>(); } else { return null; } }
void OnCollisionEnter(Collision other) { Sliceable otherSliceable = other.collider.GetComponent <Sliceable>(); SliceThis(otherSliceable); }
private Mesh getMesh(Sliceable s) { GameObject holder = getMeshHolder(s); Renderer renderer = holder.GetComponent<Renderer>(); Mesh mesh = null; if(renderer is MeshRenderer) { mesh = holder.GetComponent<MeshFilter>().mesh; } else if(renderer is SkinnedMeshRenderer) { SkinnedMeshRenderer smr = renderer as SkinnedMeshRenderer; mesh = new Mesh(); smr.BakeMesh(mesh); meshDeletionQueue.Enqueue(mesh); } return mesh; }
public GameObject[] splitByPlane(GameObject go, Vector4 plane, bool destroyOriginal) { if (go.GetComponentInChildren <SkinnedMeshRenderer>() != null) { return(splitByPlaneRD(go, plane, destroyOriginal)); } Sliceable sliceable = ensureSliceable(go); if (!sliceable.currentlySliceable) { GameObject[] result = { go }; return(result); } InfillConfiguration[] ourInfills = sliceable.infillers.Length > 0 ? sliceable.infillers : infills; MeshCache c = null; do { MeshFilter filter = getMeshFilter(sliceable); Mesh m = filter.sharedMesh; if (m == null) { break; } if (meshCaches != null && meshCaches.ContainsKey(m)) { c = meshCaches[m]; //The mesh cache will be directly modified under the assumption that this will be discarded shortly //and thus picked up by the GC. It will grow in size; it will not shrink. Thus we do not want to //operate on the original, semi-persistent mesh caches that were preloaded on boot. Instead, we want //to make a clone. if (c.wasPreloaded) { c = c.clone(); } } else { c = cacheFromGameObject(sliceable, true); } }while(false); if (c == null) { Debug.LogWarning("Turbo Slicer cannot find mesh filter in object '" + go.name + "' in scene '" + Application.loadedLevelName + "'! Only objects featuring a mesh filter can be sliced."); GameObject[] result = { go }; return(result); } int submeshCount = c.indices.Length; //We're going to create two new tentative meshes which contain ALL original vertices in order, //plus room for new vertices. Not all of these copied vertices will be addressed, but copying them //over eliminates the need to remove doubles and do an On^2 search. TurboList <int>[] _frontIndices = new TurboList <int> [submeshCount]; TurboList <int>[] _backIndices = new TurboList <int> [submeshCount]; PlaneTriResult[] sidePlanes = new PlaneTriResult[c.vertices.Count]; { Vector3[] vertices = c.vertices.array; for (int i = 0; i < sidePlanes.Length; i++) { sidePlanes[i] = getSidePlane(ref vertices[i], ref plane); } } for (int j = 0; j < submeshCount; j++) { int initialCapacityIndices = Mathf.RoundToInt((float)c.indices[j].Length * factorOfSafetyIndices); _frontIndices[j] = new TurboList <int>(initialCapacityIndices); _backIndices[j] = new TurboList <int>(initialCapacityIndices); int[] _indices = c.indices[j]; TurboList <int> frontIndices = _frontIndices[j]; TurboList <int> backIndices = _backIndices[j]; TurboList <int> splitPending = new TurboList <int>(initialCapacityIndices); int[] indices = new int[3]; for (int i = 0; i < _indices.Length;) { indices[0] = _indices[i++]; indices[1] = _indices[i++]; indices[2] = _indices[i++]; // compute the side of the plane each vertex is on PlaneTriResult r1 = sidePlanes[indices[0]]; PlaneTriResult r2 = sidePlanes[indices[1]]; PlaneTriResult r3 = sidePlanes[indices[2]]; if (r1 == r2 && r1 == r3) // if all three vertices are on the same side of the plane. { if (r1 == PlaneTriResult.PTR_FRONT) // if all three are in front of the plane, then copy to the 'front' output triangle. { frontIndices.AddArray(indices); } else { backIndices.AddArray(indices); } } else { splitPending.AddArray(indices); } } InfillConfiguration ifc = null; if (j < c.mats.Length) { Material mat = c.mats[j]; foreach (InfillConfiguration _ifc in ourInfills) { if (_ifc.material == mat) { ifc = _ifc; } } } splitTriangles(plane, splitPending.ToArray(), c, ifc, frontIndices, backIndices); } GameObject[] results; bool onlyHaveOne = true; for (int i = 0; i < c.indices.Length; i++) { onlyHaveOne &= _frontIndices[i].Count == 0 || _backIndices[i].Count == 0; } if (onlyHaveOne) { //Do nothing results = new GameObject[1]; results[0] = go; } else { MeshCache frontCache = new MeshCache(); frontCache.vertices = c.vertices; if (sliceable.channelNormals) { frontCache.normals = c.normals; } frontCache.UVs = c.UVs; frontCache.mats = c.mats; MeshCache backCache = new MeshCache(); backCache.vertices = c.vertices; if (sliceable.channelNormals) { backCache.normals = c.normals; } backCache.UVs = c.UVs; backCache.mats = c.mats; frontCache.indices = new int[submeshCount][]; backCache.indices = new int[submeshCount][]; for (int i = 0; i < submeshCount; i++) { frontCache.indices[i] = _frontIndices[i].ToArray(); backCache.indices[i] = _backIndices[i].ToArray(); } Vector3[] geoSubsetOne, geoSubsetTwo; Vector3[] normalsSubsetOne = null, normalsSubsetTwo = null; Vector2[] uvSubsetOne, uvSubsetTwo; int[][] indexSubsetOne, indexSubsetTwo; indexSubsetOne = new int[submeshCount][]; indexSubsetTwo = new int[submeshCount][]; //Perfect subset will inflate the array list size if needed to the exact figure. So if we estimate 0, //and there is 1 submesh, than we will have 1 allocation, and this is optimal. Estimation can only help //if we have THREE or more submeshes, which is a silly scenario for anyone concerned about performance. int estimateOne = 0, estimateTwo = 0; TurboList <Vector3> _geoSubsetOne = null, _geoSubsetTwo = null, _normalSubsetOne = null, _normalSubsetTwo = null; TurboList <Vector2> _uvSubsetOne = null, _uvSubsetTwo = null; _geoSubsetOne = new TurboList <Vector3>(estimateOne); _geoSubsetTwo = new TurboList <Vector3>(estimateTwo); if (sliceable.channelNormals) { _normalSubsetOne = new TurboList <Vector3>(estimateOne); _normalSubsetTwo = new TurboList <Vector3>(estimateTwo); } _uvSubsetOne = new TurboList <Vector2>(estimateOne); _uvSubsetTwo = new TurboList <Vector2>(estimateTwo); int transferTableMaximumKey = c.vertices.Count; int[] transferTableOne = new int[transferTableMaximumKey]; int[] transferTableTwo = new int[transferTableMaximumKey]; for (int i = 0; i < transferTableOne.Length; i++) { transferTableOne[i] = -1; } for (int i = 0; i < transferTableTwo.Length; i++) { transferTableTwo[i] = -1; } for (int i = 0; i < submeshCount; i++) { perfectSubset(_frontIndices[i], c.vertices, c.normals, c.UVs, out indexSubsetOne[i], _geoSubsetOne, _normalSubsetOne, _uvSubsetOne, ref transferTableOne); } for (int i = 0; i < submeshCount; i++) { perfectSubset(_backIndices[i], c.vertices, c.normals, c.UVs, out indexSubsetTwo[i], _geoSubsetTwo, _normalSubsetTwo, _uvSubsetTwo, ref transferTableTwo); } geoSubsetOne = _geoSubsetOne.ToArray(); geoSubsetTwo = _geoSubsetTwo.ToArray(); if (sliceable.channelNormals) { normalsSubsetOne = _normalSubsetOne.ToArray(); normalsSubsetTwo = _normalSubsetTwo.ToArray(); } uvSubsetOne = _uvSubsetOne.ToArray(); uvSubsetTwo = _uvSubsetTwo.ToArray(); //Note that we do not explicitly call recalculate bounds because (as per the manual) this is implicit in an //assignment to vertices whenever the vertex count changes from zero to non-zero. Mesh frontMesh = new Mesh(); Mesh backMesh = new Mesh(); GameObject frontObject, backObject; createResultObjects(go, sliceable, false, plane, out frontObject, out backObject); getMeshFilter(frontObject.GetComponent <Sliceable>()).mesh = frontMesh; getMeshFilter(backObject.GetComponent <Sliceable>()).mesh = backMesh; frontMesh.vertices = geoSubsetOne; backMesh.vertices = geoSubsetTwo; if (sliceable.channelNormals) { frontMesh.normals = normalsSubsetOne; backMesh.normals = normalsSubsetTwo; } frontMesh.uv = uvSubsetOne; backMesh.uv = uvSubsetTwo; frontMesh.subMeshCount = submeshCount; backMesh.subMeshCount = submeshCount; for (int i = 0; i < submeshCount; i++) { frontMesh.SetTriangles(indexSubsetOne[i], i); backMesh.SetTriangles(indexSubsetTwo[i], i); } if (meshCaches != null) { if (go.GetComponent <DeletionCallback>() == null) { frontObject.AddComponent <DeletionCallback>(); backObject.AddComponent <DeletionCallback>(); } DeletionCallback frontCallback = frontObject.GetComponent <DeletionCallback>(); DeletionCallback backCallback = backObject.GetComponent <DeletionCallback>(); frontCallback.deletionListener = new DeletionOccurred(this.releaseCacheByMesh); backCallback.deletionListener = new DeletionOccurred(this.releaseCacheByMesh); frontCallback.mesh = frontMesh; backCallback.mesh = backMesh; meshCaches[frontMesh] = frontCache; meshCaches[backMesh] = backCache; } else { DeletionCallback frontCallback = frontObject.GetComponent <DeletionCallback>(); DeletionCallback backCallback = backObject.GetComponent <DeletionCallback>(); if (frontCallback != null) { GameObject.DestroyImmediate(frontCallback); } if (backCallback != null) { GameObject.DestroyImmediate(backCallback); } } if (destroyOriginal) { GameObject.Destroy(go); } results = new GameObject[2]; results[0] = frontObject; results[1] = backObject; if (sliceable != null && sliceable.refreshColliders) { foreach (GameObject r in results) { Collider collider = r.collider; if (collider != null) { if (collider is BoxCollider) { GameObject.DestroyImmediate(collider); r.AddComponent <BoxCollider>(); } else if (collider is SphereCollider) { GameObject.DestroyImmediate(collider); r.AddComponent <SphereCollider>(); } else if (collider is MeshCollider) { MeshCollider mc = (MeshCollider)collider; bool isFront = r == frontObject; Mesh mesh = isFront ? frontMesh : backMesh; mc.sharedMesh = mesh; } } } } if (sliceable != null) { sliceable.handleSlice(results); } } return(results); }
private void SliceThis(Sliceable otherSliceable) { if(!childSliced.Contains(otherSliceable) && otherSliceable != null && !justSliced.Contains(otherSliceable) && !pendingSlices.Contains(otherSliceable)) { pendingSlices.Add(otherSliceable); Debug.Log("slicing: "+otherSliceable.gameObject.name); // this.GetComponent<Collider>().enabled=false; } }
void Awake() { //We assume this will work because, with the RequireComponent attribute, we asked the Unity editor //to ensure the presence of a Sliceable component on the same object. sliceable = gameObject.GetComponent <Sliceable>(); }
//Setter getters public void SetSliceable(Sliceable slice) { this._sliceable = slice; }
private void createResultObjects(GameObject go, Sliceable sliceable, bool forceCloning, Vector4 plane, out GameObject frontObject, out GameObject backObject) { Transform goTransform = go.transform; Dictionary<string,Transform> transformByName; Dictionary<string,bool> frontPresence, backPresence; determinePresence(goTransform, plane, out transformByName, out frontPresence, out backPresence); bool useAlternateForFront, useAlternateForBack; if(sliceable.alternatePrefab == null) { useAlternateForFront = false; useAlternateForBack = false; } else if(sliceable.alwaysCloneFromAlternate) { useAlternateForFront = true; useAlternateForBack = true; } else { useAlternateForFront = sliceable.cloneAlternate(frontPresence); useAlternateForBack = sliceable.cloneAlternate(backPresence); } Object frontSource = useAlternateForFront ? sliceable.alternatePrefab : go; Object backSource = useAlternateForBack ? sliceable.alternatePrefab : go; frontObject = (GameObject) GameObject.Instantiate(frontSource); backObject = (GameObject) GameObject.Instantiate(backSource); handleHierarchy(frontObject.transform, frontPresence, transformByName); handleHierarchy(backObject.transform, backPresence, transformByName); Transform parent = goTransform.parent; Vector3 position = goTransform.localPosition; Vector3 scale = goTransform.localScale; Quaternion rotation = goTransform.localRotation; frontObject.transform.parent = parent; frontObject.transform.localPosition = position; frontObject.transform.localScale = scale; backObject.transform.parent = parent; backObject.transform.localPosition = position; backObject.transform.localScale = scale; frontObject.transform.localRotation = rotation; backObject.transform.localRotation = rotation; frontObject.layer = go.layer; backObject.layer = go.layer; Rigidbody originalRigidBody = go.GetComponent<Rigidbody>(); if(originalRigidBody != null) { Rigidbody frontRigidBody = frontObject.GetComponent<Rigidbody>(); Rigidbody backRigidBody = backObject.GetComponent<Rigidbody>(); if(frontRigidBody != null) { frontRigidBody.angularVelocity = originalRigidBody.angularVelocity; frontRigidBody.velocity = originalRigidBody.velocity; frontRigidBody.useGravity = true; } if(backRigidBody != null) { backRigidBody.angularVelocity = originalRigidBody.angularVelocity; backRigidBody.velocity = originalRigidBody.velocity; backRigidBody.useGravity = true; } } // if( frontObject.tag == "TargetClone" ) // { // frontObject.GetComponent<Collider> ().enabled = false; // backObject.GetComponent<Collider> ().enabled = false; // } // else // { frontObject.GetComponent<Collider> ().isTrigger = false; backObject.GetComponent<Collider> ().isTrigger = false; // } if( frontObject.tag == "Target" ) frontObject.tag = backObject.tag = "TargetClone"; }
public override void OnInspectorGUI() { bool someTargetsAreUnvetted = false; bool someTargetsHaveMultipleRenderers = false; List <Renderer> relevantRenderers = new List <Renderer>(); List <Renderer> allRenderers = new List <Renderer>(); foreach (Object o in targets) { Sliceable s = (Sliceable)o; Component[] _allRenderersOnThisTarget = s.GetComponentsInChildren(typeof(Renderer), true); Renderer[] allRenderersOnThisTarget = new Renderer[_allRenderersOnThisTarget.Length]; for (int i = 0; i < _allRenderersOnThisTarget.Length; i++) { allRenderersOnThisTarget[i] = _allRenderersOnThisTarget[i] as Renderer; } allRenderers.AddRange(allRenderersOnThisTarget); if (allRenderersOnThisTarget.Length == 1) { relevantRenderers.Add(allRenderersOnThisTarget[0]); } else if (s.explicitlySelectedMeshHolder != null) { relevantRenderers.Add(s.explicitlySelectedMeshHolder.GetComponent(typeof(Renderer)) as Renderer); } else { someTargetsAreUnvetted = true; } someTargetsHaveMultipleRenderers |= allRenderersOnThisTarget.Length > 1; } EditorGUILayout.PropertyField(refreshCollidersProperty, new GUIContent("Refresh colliders")); EditorGUILayout.PropertyField(alternatePrefabProperty, new GUIContent("Alternate prefab")); EditorGUILayout.PropertyField(shreddableProperty, new GUIContent("Shreddable")); bool atLeastSomeHaveAlternatePrefab = alternatePrefabProperty.hasMultipleDifferentValues || alternatePrefabProperty.objectReferenceValue != null; if (atLeastSomeHaveAlternatePrefab) { EditorGUILayout.PropertyField(alwaysCloneFromAlternateProperty, new GUIContent("Always clone from alternate")); } EditorGUILayout.PropertyField(channelNormalsProperty, new GUIContent("Process Normals")); EditorGUILayout.PropertyField(channelTangentsProperty, new GUIContent("Process Tangents")); EditorGUILayout.PropertyField(channelUV2Property, new GUIContent("Process UV2")); EditorGUILayout.Separator(); //Ensure that all the targets are vetted and if they're not, we can only vet them one at a time //through the unity inspector. if (relevantRenderers.Count == 0) { EditorGUILayout.LabelField("No mesh renderers found!"); } else if (someTargetsAreUnvetted && (targets.Length > 1)) { EditorGUILayout.LabelField("Cannot multi-edit: Some objects have multiple"); EditorGUILayout.LabelField("meshes. Please vet them individually."); } else if (someTargetsHaveMultipleRenderers && (targets.Length == 1)) { EditorGUILayout.LabelField("This object has multiple meshes. Specify the primary."); int selectedRenderer = 0; GameObject explicitlySelectedMeshHolder = explicitlySelectedMeshHolderProperty.objectReferenceValue as GameObject; if (explicitlySelectedMeshHolder != null) { Renderer r = explicitlySelectedMeshHolder.GetComponent <Renderer>(); if (r != null) { selectedRenderer = allRenderers.IndexOf(r); } } string[] displayedOptions = new string[allRenderers.Count]; for (int i = 0; i < displayedOptions.Length; i++) { displayedOptions[i] = allRenderers[i].name; } selectedRenderer = EditorGUILayout.Popup("Slice Mesh", selectedRenderer, displayedOptions); Renderer renderer = allRenderers[selectedRenderer]; explicitlySelectedMeshHolderProperty.objectReferenceValue = renderer.gameObject; } serializedObject.ApplyModifiedProperties(); //Assuming we're all legit, let's multi-edit the infillers. if (!someTargetsAreUnvetted) { List <Material> mats = new List <Material>(); foreach (Renderer r in relevantRenderers) { Material[] _mats = r.sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } } if (mats.Count > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } } if (!someTargetsAreUnvetted) { var mats = new List <Material>(); var preexistingInfillers = new List <InfillConfiguration>(); foreach (Object o in targets) { Sliceable s = o as Sliceable; Renderer renderer; if (s.explicitlySelectedMeshHolder != null) { renderer = s.explicitlySelectedMeshHolder.GetComponent <Renderer>(); } else { renderer = s.gameObject.GetComponent <Renderer>(); } if (renderer != null) { Material[] _mats = renderer.sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } } preexistingInfillers.AddRange(s.infillers); } InfillConfiguration[] infillers = new InfillConfiguration[mats.Count]; var forceDirty = false; for (int i = 0; i < mats.Count; i++) { Material mat = mats[i]; InfillConfiguration infiller = null; foreach (var _infiller in preexistingInfillers) { if (_infiller.material == mat) { infiller = _infiller; break; } } //If there is no infiller, than the UI will create one. However, the GUI will not be seen as changed, and //therefore if we do not set some flag, than the code lower down will not recognize that it ought to //set the item as 'dirty'. if (infiller == null) { infiller = new InfillConfiguration(); infiller.material = mat; infiller.regionForInfill = new Rect(0f, 0f, 1f, 1f); forceDirty = true; } infillers[i] = infiller; } foreach (var infiller in infillers) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material: " + infiller.material.name); infiller.regionForInfill = EditorGUILayout.RectField("Region for infill", infiller.regionForInfill); } if (GUI.changed || forceDirty) { foreach (Object o in targets) { Sliceable s = o as Sliceable; s.infillers = new InfillConfiguration[infillers.Length]; System.Array.Copy(infillers, s.infillers, infillers.Length); EditorUtility.SetDirty(o); } } } }
public override void OnInspectorGUI() { bool someTargetsHaveMultipleRenderers = false; var allRenderers = new List <Renderer>(); foreach (Object o in targets) { Sliceable s = (Sliceable)o; Component[] _allRenderersOnThisTarget = s.GetComponentsInChildren(typeof(Renderer), true); Renderer[] allRenderersOnThisTarget = new Renderer[_allRenderersOnThisTarget.Length]; for (int i = 0; i < _allRenderersOnThisTarget.Length; i++) { allRenderersOnThisTarget[i] = _allRenderersOnThisTarget[i] as Renderer; } allRenderers.AddRange(allRenderersOnThisTarget); someTargetsHaveMultipleRenderers |= allRenderersOnThisTarget.Length > 1; } EditorGUILayout.PropertyField(refreshCollidersProperty, new GUIContent("Refresh colliders")); EditorGUILayout.PropertyField(alternatePrefabProperty, new GUIContent("Alternate prefab")); EditorGUILayout.PropertyField(shreddableProperty, new GUIContent("Shreddable")); bool atLeastSomeHaveAlternatePrefab = alternatePrefabProperty.hasMultipleDifferentValues || alternatePrefabProperty.objectReferenceValue != null; if (atLeastSomeHaveAlternatePrefab) { EditorGUILayout.PropertyField(alwaysCloneFromAlternateProperty, new GUIContent("Always clone from alternate")); } EditorGUILayout.PropertyField(channelNormalsProperty, new GUIContent("Process Normals")); EditorGUILayout.PropertyField(channelTangentsProperty, new GUIContent("Process Tangents")); EditorGUILayout.PropertyField(channelUV2Property, new GUIContent("Process UV2")); EditorGUILayout.Separator(); //Ensure that all the targets are vetted and if they're not, we can only vet them one at a time //through the unity inspector. if (allRenderers.Count == 0) { EditorGUILayout.LabelField("No mesh renderers found!"); } serializedObject.ApplyModifiedProperties(); //Assuming we're all legit, let's multi-edit the infillers. var mats = new HashSet <Material>(); foreach (var r in allRenderers) { Material[] _mats = r.sharedMaterials; foreach (Material mat in _mats) { mats.Add(mat); } } if (mats.Count > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } var preexistingInfillers = new List <InfillConfiguration>(); foreach (Object o in targets) { Sliceable s = o as Sliceable; Renderer renderer; renderer = s.gameObject.GetComponent <Renderer>(); if (renderer != null) { Material[] _mats = renderer.sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } } preexistingInfillers.AddRange(s.infillers); } var infillersBuilder = new List <InfillConfiguration>(); var forceDirty = false; foreach (var mat in mats) { InfillConfiguration infiller = null; foreach (var _infiller in preexistingInfillers) { if (_infiller.material == mat) { infiller = _infiller; break; } } //If there is no infiller, than the UI will create one. However, the GUI will not be seen as changed, and //therefore if we do not set some flag, than the code lower down will not recognize that it ought to //set the item as 'dirty'. if (infiller == null) { infiller = new InfillConfiguration(); infiller.material = mat; infiller.regionForInfill = new Rect(0f, 0f, 1f, 1f); forceDirty = true; } infillersBuilder.Add(infiller); } foreach (var infiller in infillersBuilder) { EditorGUILayout.Separator(); var material = infiller.material; var materialName = material == null ? "Null" : material.name; EditorGUILayout.LabelField("Material: " + materialName); infiller.regionForInfill = EditorGUILayout.RectField("Region for infill", infiller.regionForInfill); } if (GUI.changed || forceDirty) { var infillersArray = infillersBuilder.ToArray(); foreach (Object o in targets) { Sliceable s = o as Sliceable; s.infillers = infillersArray; EditorUtility.SetDirty(o); } } }
public override void OnInspectorGUI() { bool someTargetsAreUnvetted = false; bool someTargetsHaveMultipleRenderers = false; List <Renderer> relevantRenderers = new List <Renderer>(); List <Renderer> allRenderers = new List <Renderer>(); foreach (Object o in targets) { Sliceable s = (Sliceable)o; Component[] _allRenderersOnThisTarget = s.GetComponentsInChildren(typeof(Renderer), true); Renderer[] allRenderersOnThisTarget = new Renderer[_allRenderersOnThisTarget.Length]; for (int i = 0; i < _allRenderersOnThisTarget.Length; i++) { allRenderersOnThisTarget[i] = _allRenderersOnThisTarget[i] as Renderer; } allRenderers.AddRange(allRenderersOnThisTarget); if (allRenderersOnThisTarget.Length == 1) { relevantRenderers.Add(allRenderersOnThisTarget[0]); } else if (s.explicitlySelectedMeshHolder != null) { relevantRenderers.Add(s.meshHolder.GetComponent(typeof(Renderer)) as Renderer); } else { someTargetsAreUnvetted = true; } someTargetsHaveMultipleRenderers |= allRenderersOnThisTarget.Length > 1; } EditorGUILayout.PropertyField(refreshCollidersProperty, new GUIContent("Refresh colliders")); EditorGUILayout.PropertyField(alternatePrefabProperty, new GUIContent("Alternate prefab")); bool atLeastSomeHaveAlternatePrefab = alternatePrefabProperty.hasMultipleDifferentValues || alternatePrefabProperty.objectReferenceValue != null; if (atLeastSomeHaveAlternatePrefab) { EditorGUILayout.PropertyField(alwaysCloneFromAlternateProperty, new GUIContent("Always clone from alternate")); } EditorGUILayout.PropertyField(channelNormalsProperty, new GUIContent("Process Normals")); EditorGUILayout.PropertyField(channelTangentsProperty, new GUIContent("Process Tangents")); EditorGUILayout.PropertyField(channelUV2Property, new GUIContent("Process UV2")); EditorGUILayout.Separator(); //Ensure that all the targets are vetted and if they're not, we can only vet them one at a time //through the unity inspector. if (relevantRenderers.Count == 0) { EditorGUILayout.LabelField("No mesh renderers found!"); } else if (someTargetsAreUnvetted && (targets.Length > 1)) { EditorGUILayout.LabelField("Cannot multi-edit: Some objects have multiple"); EditorGUILayout.LabelField("meshes. Please vet them individually."); } else if (someTargetsHaveMultipleRenderers && (targets.Length == 1)) { EditorGUILayout.LabelField("This object has multiple meshes. Specify the primary."); int selectedRenderer = 0; GameObject explicitlySelectedMeshHolder = explicitlySelectedMeshHolderProperty.objectReferenceValue as GameObject; if (explicitlySelectedMeshHolder != null) { Renderer r = explicitlySelectedMeshHolder.GetComponent <Renderer>(); if (r != null) { selectedRenderer = allRenderers.IndexOf(r); } } string[] displayedOptions = new string[allRenderers.Count]; for (int i = 0; i < displayedOptions.Length; i++) { displayedOptions[i] = allRenderers[i].name; } selectedRenderer = EditorGUILayout.Popup("Slice Mesh", selectedRenderer, displayedOptions); Renderer renderer = allRenderers[selectedRenderer]; explicitlySelectedMeshHolderProperty.objectReferenceValue = renderer.gameObject; } serializedObject.ApplyModifiedProperties(); //Assuming we're all legit, let's multi-edit the infillers. if (!someTargetsAreUnvetted) { List <Material> mats = new List <Material>(); foreach (Renderer r in relevantRenderers) { Material[] _mats = r.sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } } if (mats.Count > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } } if (!someTargetsAreUnvetted) { List <Material> mats = new List <Material>(); List <TurboSlice.InfillConfiguration> preexistingInfillers = new List <TurboSlice.InfillConfiguration>(); foreach (Object o in targets) { Sliceable s = o as Sliceable; Material[] _mats = s.meshHolder.GetComponent <Renderer>().sharedMaterials; foreach (Material mat in _mats) { if (mats.Contains(mat) == false) { mats.Add(mat); } } preexistingInfillers.AddRange(s.infillers); } TurboSlice.InfillConfiguration[] infillers = new TurboSlice.InfillConfiguration[mats.Count]; for (int i = 0; i < mats.Count; i++) { Material mat = mats[i]; TurboSlice.InfillConfiguration infiller = null; foreach (TurboSlice.InfillConfiguration _infiller in preexistingInfillers) { if (_infiller.material == mat) { infiller = _infiller; break; } } if (infiller == null) { infiller = new TurboSlice.InfillConfiguration(); infiller.material = mat; infiller.regionForInfill = new Rect(0f, 0f, 1f, 1f); } infillers[i] = infiller; } foreach (TurboSlice.InfillConfiguration infiller in infillers) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material: " + infiller.material.name); infiller.regionForInfill = EditorGUILayout.RectField("Region for infill", infiller.regionForInfill); } if (GUI.changed) { foreach (Object o in targets) { Sliceable s = o as Sliceable; s.infillers = new TurboSlice.InfillConfiguration[infillers.Length]; System.Array.Copy(infillers, s.infillers, infillers.Length); EditorUtility.SetDirty(o); } } } /*if(!someTargetsAreUnvetted) * { * List<Material> mats = new List<Material>(); * * foreach(Renderer r in relevantRenderers) * { * Material[] _mats = r.sharedMaterials; * foreach(Material mat in _mats) * { * if(mats.Contains(mat) == false) mats.Add(mat); * } * } * * if(mats.Count > 0) * { * EditorGUILayout.LabelField("For each material, define what region is used for infill."); * } * * foreach(Material mat in mats) * { * //Is this material represented in our array? * * EditorGUILayout.Separator(); * * SerializedProperty infiller = null; * * for(int i = 0; i < infillersProperty.arraySize; i++) * { * SerializedProperty _infiller = infillersProperty.GetArrayElementAtIndex(i); * _infiller. * SerializedProperty _mat = _infiller.FindPropertyRelative("material"); * if(_mat != null) * { * Material thisMat = _mat.objectReferenceValue as Material; * if(thisMat == mat) * { * infiller = _infiller; * } * } * } * * if(infiller == null) * { * infillersProperty.InsertArrayElementAtIndex(0); * infiller = infillersProperty.GetArrayElementAtIndex(0); * * SerializedProperty _mat = infiller.FindPropertyRelative("material"); * _mat.objectReferenceValue = mat; * } * * EditorGUILayout.LabelField("Material: " + mat.name); * * SerializedProperty regionForInfillProperty = infiller.FindPropertyRelative("regionForInfill"); * * EditorGUILayout.PropertyField(regionForInfillProperty, new GUIContent("Region for infill")); * } * * { * List<Material> observedMats = new List<Material>(); * * for(int i = 0; i < infillersProperty.arraySize; i++) * { * SerializedProperty _infiller = infillersProperty.GetArrayElementAtIndex(i); * SerializedProperty _mat = _infiller.FindPropertyRelative("material"); * Material mat = _mat.objectReferenceValue as Material; * bool delete = mat == null || observedMats.Contains(mat); * if(delete) infillersProperty.DeleteArrayElementAtIndex(i--); * else observedMats.Add(mat); * } * } * }*/ }
public override void OnInspectorGUI() { Sliceable s = (Sliceable)target; Renderer[] renderers = s.GetComponentsInChildren <Renderer>(true); bool isAnimated = false; foreach (Renderer r in renderers) { isAnimated |= r is SkinnedMeshRenderer; } //TurboSlice.supportsSkinned is a const that is overridden by the presence of Ragdoll Slicer #pragma warning disable 0162 if (isAnimated && !TurboSlice.supportsSkinned) { EditorGUILayout.LabelField("Error!"); EditorGUILayout.LabelField("Skinned meshes are not supported."); return; } s.refreshColliders = EditorGUILayout.Toggle("Refresh colliders", s.refreshColliders); s.alternatePrefab = EditorGUILayout.ObjectField("Alternate prefab", (Object)s.alternatePrefab, typeof(GameObject), false); if (s.alternatePrefab != null) { s.alwaysCloneFromAlternate = EditorGUILayout.Toggle("Always clone from alternate", s.alwaysCloneFromAlternate); } s.currentlySliceable = EditorGUILayout.Toggle("Currently Sliceable", s.currentlySliceable); s.category = EditorGUILayout.TextField("Category", s.category); s.channelNormals = EditorGUILayout.Toggle("Process Normals", s.channelNormals); s.channelTangents = EditorGUILayout.Toggle("Process Tangents", s.channelTangents); s.channelUV2 = EditorGUILayout.Toggle("Process UV2", s.channelUV2); Renderer renderer = null; if (renderers.Length == 0) { EditorGUILayout.LabelField("No mesh renderers found in this object!"); } else if (renderers.Length > 1) { EditorGUILayout.LabelField("This object has multiple meshes. Specify the primary."); int selectedRenderer = 0; if (s.explicitlySelectedMeshHolder != null) { Renderer r = s.explicitlySelectedMeshHolder.GetComponent <Renderer>(); if (r != null) { selectedRenderer = System.Array.IndexOf <Renderer>(renderers, r); } } string[] displayedOptions = new string[renderers.Length]; for (int i = 0; i < displayedOptions.Length; i++) { displayedOptions[i] = renderers[i].name; } selectedRenderer = EditorGUILayout.Popup("Slice Mesh", selectedRenderer, displayedOptions); renderer = renderers[selectedRenderer]; s.explicitlySelectedMeshHolder = renderer.gameObject; } else if (renderers.Length == 1) { renderer = renderers[0]; s.explicitlySelectedMeshHolder = renderer.gameObject; } if (renderer != null) { List <TurboSlice.InfillConfiguration> newInfillers = new List <TurboSlice.InfillConfiguration>(); Material[] mats = renderer.sharedMaterials; if (mats.Length > 0) { EditorGUILayout.LabelField("For each material, define what region is used for infill."); } foreach (Material mat in mats) { //Is this material represented in our array? EditorGUILayout.Separator(); if (s.infillers == null) { s.infillers = new TurboSlice.InfillConfiguration[0]; } TurboSlice.InfillConfiguration infiller = null; foreach (TurboSlice.InfillConfiguration ifc in s.infillers) { if (ifc.material == mat) { infiller = ifc; break; } } EditorGUILayout.LabelField("Material: " + mat.name); bool hasIt = EditorGUILayout.Toggle("Infill this material", infiller != null); if (hasIt && infiller == null) { infiller = new TurboSlice.InfillConfiguration(); infiller.material = mat; } else if (!hasIt) { infiller = null; } if (infiller != null) { newInfillers.Add(infiller); infiller.regionForInfill = EditorGUILayout.RectField(infiller.regionForInfill); } } s.infillers = newInfillers.ToArray(); } if (GUI.changed) { EditorUtility.SetDirty(target); } }
void Awake() { sliceable = gameObject.GetComponent <Sliceable>(); }