/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// CreateNewDecal /// # Create a new mesh decal in the scene /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// public GenericMeshDecal CreateNewMeshDecal(Material decalMaterial, Transform parent, Vector3 point, Vector3 normal, float scaleMultiplier, Vector2 rotationRange, bool attachDecalToCollisionObject) { //print ("CreateNewDecal"); GenericMeshDecal actualDecal = Instantiate(decalPrefab.gameObject).GetComponent <GenericMeshDecal> (); actualDecal.material = decalMaterial; actualDecal.transform.position = point + 0.001f * normal; actualDecal.transform.localScale = scaleMultiplier * actualDecal.transform.localScale; actualDecal.transform.rotation = Quaternion.FromToRotation(Vector3.up, normal); if (attachDecalToCollisionObject) { actualDecal.transform.parent = parent; } else { GameObject decalsContainer = BasicFunctions.CreateContainerIfNotExists(BasicDefines.MESH_DECAL_CONTAINER_NAME); actualDecal.transform.parent = decalsContainer.transform; } actualDecal.rotationRange = rotationRange; actualDecal.name = "RunTimeDecal"; actualDecal.UpdateDecallShape(true, false); return(actualDecal.GetComponent <GenericMeshDecal> ()); }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// MergeAllDecals /// # Merge all decals in scene /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void MergeAllDecals() { GenericMeshDecal[] actualDecalsInSceneList = (GenericMeshDecal[])GameObject.FindObjectsOfType(typeof(GenericMeshDecal)); List <GameObject> actualDecalsInSceneGameObjectList = new List <GameObject> (); for (int i = 0; i < actualDecalsInSceneList.Count(); i++) { Undo.RegisterFullObjectHierarchyUndo(actualDecalsInSceneList [i], "Merge decals: delete originals"); GenericMeshDecal actualDecal = actualDecalsInSceneList [i].gameObject.GetComponent <GenericMeshDecal> (); if (actualDecal) { actualDecalsInSceneGameObjectList.Add(actualDecal.gameObject); } } if (actualDecalsInSceneGameObjectList.Count > 0) { MeshMergerer.Merge(actualDecalsInSceneGameObjectList, mergedObjectName, deleteOldDecals); } else { EditorUtility.DisplayDialog("ERROR", "There are not decals in scene", "OK"); } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// CreateDecal /// # Create a decal for a collision /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void CreateDecal(Collision col) { if (counterBetweenDecalCreations <= 0) { counterBetweenDecalCreations = timeBetweenDecalCreations; int numberOfCreatedDecals = 0; foreach (ContactPoint contact in col.contacts) { float actualScaleMultiplier = Random.Range(scaleMultiplierRange.x, scaleMultiplierRange.y); if (!contact.otherCollider.gameObject.GetComponent <NotStainableObject> ()) { if (DecalInGameManager.DECAL_INGAME_MANAGER) { GenericMeshDecal actualDecal = DecalInGameManager.DECAL_INGAME_MANAGER.CreateNewMeshDecal(decalMaterial, contact.otherCollider.transform, contact.point, contact.normal, actualScaleMultiplier, rotationRange, false); actualDecal.SetDestroyable(true, destroyTime, destroySpeed); numberOfCreatedDecals++; } } if (numberOfCreatedDecals >= maxDecalsCreatedPerCollision) { break; } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// OnParticleCollision /// # Hhandle collisions /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void OnParticleCollision(GameObject other) { //print ("other name: " + other.name); int safeLength = part.GetSafeCollisionEventSize(); if (collisionEvents.Length < safeLength) { collisionEvents = new ParticleCollisionEvent[safeLength]; } int numCollisionEvents = part.GetCollisionEvents(other, collisionEvents); if (DecalInGameManager.DECAL_INGAME_MANAGER) { for (int i = 0; i < numCollisionEvents; i++) { if (timeBewteenDecals <= 0) { timeBewteenDecals = .5f; //print ("Create decal"); #if UNITY_5_0 GenericMeshDecal actualDecal = DecalInGameManager.DECAL_INGAME_MANAGER.CreateNewMeshDecal(decalMaterial, collisionEvents[i].collider.transform, collisionEvents[i].intersection, collisionEvents[i].normal, 4, Vector2.zero, false); #else GenericMeshDecal actualDecal = DecalInGameManager.DECAL_INGAME_MANAGER.CreateNewMeshDecal(decalMaterial, collisionEvents [i].colliderComponent.transform, collisionEvents [i].intersection, collisionEvents [i].normal, 4, Vector2.zero, false); #endif actualDecal.transform.localScale = decalScale * actualDecal.transform.localScale; actualDecal.SetDestroyable(true, 2, 0.2f); } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// OnInspectorGUI /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// public override void OnInspectorGUI() { GenericMeshDecal decal = (GenericMeshDecal)target; bool updateShape = false; if (decal.material) { string actualMaterialName = decal.material.name; decal.material = EditorBasicFunctions.DrawMeshDecalElements(decal, false, new Rect(0, 0, EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight), null); if (decal.material.name != actualMaterialName) { updateShape = true; //Debug.Log ("Material Change: "+decal.material); decal.GetComponent <Renderer>().sharedMaterial = decal.material; } } if (GUI.changed || updateShape) { decal.UpdateDecallShape(false, false); } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Start /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void Start() { GenericMeshDecal d = this.gameObject.GetComponent <GenericMeshDecal> (); if (d) { d.lockedShapeAlways = true; } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// BuildMesh /// # Creates decal's mesh and applys new texture coords /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// public void BuildMesh(GenericMeshDecal decal) { MeshFilter filter = decal.GetComponent <MeshFilter> (); if (filter == null) { filter = decal.gameObject.AddComponent <MeshFilter> (); } if (decal.GetComponent <Renderer> () == null) { decal.gameObject.AddComponent <MeshRenderer> (); } decal.GetComponent <Renderer> ().material = decal.material; if (decal.material == null || decal.sprite == null) { filter.mesh = null; return; } affectedObjects = BasicFunctions.GetAllAffectedObjects(BasicFunctions.GetTransformBounds(decal.transform), decal.affectedLayers); foreach (GameObject go in affectedObjects) { if (!go.GetComponent <WayPoint> () && !go.GetComponent <GenericMeshDecal> ()) { BasicFunctions.BuildDecalForObject(decal, go); } } BasicFunctions.Push(decal.distanceFromHit); Mesh mesh = null; if (planarDecal) { mesh = CreatePlanarMesh(1, 1); } else { mesh = BasicFunctions.CreateMesh(); //// ModifyPlanarMesh (ref mesh, 1, 1); } if (mesh != null) { mesh.name = "GenericPoly"; filter.mesh = mesh; } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// HandleAllElementsEdition /// # To edit objects in scene using Unity controls /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void HandleAllElementsEdition () { if (Event.current.type == EventType.MouseDrag) { //Debug.Log ("HandleAllElementsEdition -> MouseDrag"); if (Selection.activeGameObject) { GenericMeshDecal actualDecal = Selection.activeGameObject.GetComponent ("GenericMeshDecal") as GenericMeshDecal; if (actualDecal) { actualDecal.UpdateDecallShape (false, false); } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Update /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void Update() { rotation += 4 * Time.deltaTime; if (rotation > 360) { rotation = rotation - 360; } this.transform.RotateAround(pivot.transform.position, Vector3.up, rotation * Mathf.Deg2Rad); GenericMeshDecal d = this.gameObject.GetComponent <GenericMeshDecal> (); if (d) { d.BuildMesh(d); } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// DrawEditionMode /// # Draw al gui buttons, checboxes, ... to handle edition mode /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void DrawEditionMode () { if (!configSaver.parameters.hideBasicHelp) { EditorBasicFunctions.DrawEditorBox ("Use 'Edit Mode' to edit decals or objects, to clean scripts in the scene or to create new decals", Color.yellow, position); } EditorGUILayout.Separator (); EditorBasicFunctions.DrawEditorBox ("Edit the scene!", Color.white, position); EditorGUILayout.Separator (); GameObject actualSelectedObject = Selection.activeGameObject; if (actualSelectedObject) { GenericMeshDecal actualDecal = actualSelectedObject.GetComponent ("GenericMeshDecal") as GenericMeshDecal; GenericObject actualObject = actualSelectedObject.GetComponent ("GenericObject") as GenericObject; if (actualDecal) { EditorBasicFunctions.DrawEditorBox ("Selected decal: " + actualSelectedObject.name, Color.yellow, position); var editor = Editor.CreateEditor (actualDecal); editor.OnInspectorGUI (); } else if (actualObject) { EditorBasicFunctions.DrawEditorBox ("Selected object: " + actualSelectedObject.name, Color.yellow, position); } else { EditorBasicFunctions.DrawEditorBox ("Not editable object: " + actualSelectedObject.name, Color.gray, position); } } else { EditorBasicFunctions.DrawEditorBox ("Nothing selected!", Color.black, position); } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Start /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void Start() { positionSpline = new GenericSplineFunction(); normalSpline = new GenericSplineFunction(); for (int i = 0; i < waypointPosition.Count; i++) { positionSpline.AddPoint(waypointPosition [i], !closed && (i == waypointPosition.Count - 1)); normalSpline.AddPoint(waypointNormal [i], !closed && (i == waypointPosition.Count - 1)); } if (closed) { positionSpline.AddPoint(waypointPosition [0], true); normalSpline.AddPoint(waypointNormal [0], true); } actualDecal = this.gameObject.GetComponent <GenericMeshDecal> (); }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// MergeActualSelectedDecals /// # Merge actual selected decals into one /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void MergeActualSelectedDecals() { List <GameObject> selectedMeshDecalsList = new List <GameObject> (); for (int i = 0; i < Selection.gameObjects.Count(); i++) { GenericMeshDecal actualSelectedDecal = Selection.gameObjects [i].GetComponent <GenericMeshDecal> (); if (actualSelectedDecal) { selectedMeshDecalsList.Add(actualSelectedDecal.gameObject); } } if (selectedMeshDecalsList.Count > 0) { MeshMergerer.Merge(selectedMeshDecalsList, mergedObjectName, deleteOldDecals); } else { EditorUtility.DisplayDialog("ERROR", "You need a texture to create a decal", "OK"); } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// LoadBasics /// # Load basics /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// protected void LoadBasics() { configSaver = new ConfigSaver(); meshDecalPrefab = AssetDatabase.LoadAssetAtPath(BasicDefines.MESH_DECAL_PREFAB_PATH, typeof(GenericMeshDecal)) as GenericMeshDecal; if (!meshDecalPrefab) { Debug.Log("NOTE -> no meshDecalPrefab, verify folder: " + BasicDefines.MESH_DECAL_PREFAB_PATH); } projectedDecalPrefab = AssetDatabase.LoadAssetAtPath(BasicDefines.PROJECTED_DECAL_PREFAB_PATH, typeof(GenericProjectorDecal)) as GenericProjectorDecal; if (!projectedDecalPrefab) { Debug.Log("NOTE -> no projectedDecalPrefab, verify folder: " + BasicDefines.MESH_DECAL_PREFAB_PATH); } if (EditorBasicFunctions.GetPrefabList().Count > 0) { genericObject = EditorBasicFunctions.GetPrefabList()[0]; } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Update /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void Update() { GenericMeshDecal d = this.gameObject.GetComponent <GenericMeshDecal> (); d.BuildMesh(d); }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// HandleMeshDecalsMode /// # To insert mesh decals in scene using mouse /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// void HandleMeshDecalsMode() { if ((GetEditorTimeDiff() > 0.1f) && EditorBasicFunctions.GetMouseButtonDown(0) && EditorBasicFunctions.GetInsertModeKeyPressed() && !GetDoingSomethingSpecial()) { previousEditorTime = EditorApplication.timeSinceStartup; //Debug.Log ("Event.current.mousePosition: " + Event.current.mousePosition); Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); RaycastHit hit; //Debug.Log ("-----------------------------------------------------------"); if (Physics.Raycast(ray, out hit)) { if (lastMeshDecalsHitPoint.ToString() == hit.point.ToString()) { //Debug.Log ("NOTE: same point duplicate -> lastMeshDecalsHitPoint: " + lastMeshDecalsHitPoint); } else { //Debug.Log ("lastMeshDecalsHitPoint A: " + lastMeshDecalsHitPoint); lastMeshDecalsHitPoint = hit.point; //Debug.Log ("hit.point: " + hit.point); //Debug.Log ("lastMeshDecalsHitPoint B: " + lastMeshDecalsHitPoint); //Debug.Log ("New Decal"); //Debug.Log ("Hit position: " + hit.point); //Debug.Log ("Collider Name: " + hit.collider.name); bool setPlanarDecal = EditorBasicFunctions.planarMeshDecals; if (hit.collider.GetComponent <Terrain> ()) { //Debug.Log ("It's a terrain, set the decal as planar"); setPlanarDecal = true; } meshDecalPrefab.planarDecal = setPlanarDecal; meshDecalPrefab.comeFromEditor = setPlanarDecal; GenericMeshDecal actualDecal = Instantiate(meshDecalPrefab.gameObject).GetComponent <GenericMeshDecal> (); actualDecal.transform.position = hit.point; meshDecalPrefab.comeFromEditor = false; Vector3 finalScale = Random.Range(actualDecal.scaleRange.x, actualDecal.scaleRange.y) * actualDecal.transform.localScale; float textureAspectRatio = (float)actualDecal.material.mainTexture.width / (float)actualDecal.material.mainTexture.height; if (actualDecal.GetPlanar()) { finalScale.x = 0.5f * finalScale.x; finalScale.y = textureAspectRatio * finalScale.x; } else { finalScale.x = textureAspectRatio * finalScale.x; } //finalScale.y = finalScale.x; //finalScale.z = finalScale.x; actualDecal.transform.localScale = finalScale; actualDecal.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal); actualDecal.name = actualDecal.Generate(BasicDefines.MESH_DECAL_BASE_NAME, GetSeedForInstancies(), true, actualDecal.material.name); actualDecal.UpdateDecallShape(true, false); //Debug.Log ("actualDecal.attachToCollisionObject: " + actualDecal.attachToCollisionObject); if (actualDecal.attachToCollisionObject) { //Debug.Log ("Parent name: " + hit.collider.name); actualDecal.transform.parent = hit.collider.transform; } else { GameObject decalsContainer = BasicFunctions.CreateContainerIfNotExists(BasicDefines.MESH_DECAL_CONTAINER_NAME); actualDecal.transform.parent = decalsContainer.transform; } if (actualDecal.addCollider) { actualDecal.gameObject.AddComponent <MeshCollider> (); //actualDecal.gameObject.GetComponent<MeshCollider> ().convex = true; } actualObjectToForceSelect = actualDecal.gameObject; } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// DrawMeshDecalElements /// # Draw all mesh decal elements /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// public static Material DrawMeshDecalElements(GenericMeshDecal decal, bool comeFromEditor, Rect position, ConfigSaver configSaver) { if (decal) { EditorBasicFunctions.DrawEditorBox("Insert mesh decals: Options", Color.white, position); if ((configSaver != null) && !configSaver.parameters.hideBasicHelp) { EditorBasicFunctions.DrawEditorBox(GetInsertModeHelpString() + " mesh decals", Color.yellow, position); } EditorGUILayout.Separator(); bool showConfigOptions = true; if (configSaver != null) { configSaver.parameters.showMeshDecalsConfigOptions = EditorGUILayout.Foldout(configSaver.parameters.showMeshDecalsConfigOptions, new GUIContent("Show mesh decals configuration options", "Show mesh decals configuration options")); showConfigOptions = configSaver.parameters.showMeshDecalsConfigOptions; } if (!showConfigOptions) { } else { EditorBasicFunctions.DrawEditorBox("Configuration", Color.yellow, position); EditorGUILayout.Separator(); decal.attachToCollisionObject = EditorGUILayout.Toggle(new GUIContent("Attach to father", "Attach created decal to hit object"), decal.attachToCollisionObject); if (comeFromEditor) { decal.futureTimeLockableShape = EditorGUILayout.Toggle(new GUIContent("Future time lockable shape", "It this is checked you can use the button called 'Lock all future time lockable decals' in advance options to lock all 'futureTimeLockableShape' checked on decals, Use with caution"), decal.futureTimeLockableShape); decal.addCollider = EditorGUILayout.Toggle(new GUIContent("Add collider", "Add a collider to be detected for the next decals, Use with caution"), decal.addCollider); planarMeshDecals = EditorGUILayout.Toggle(new GUIContent("Simple planar", "Do the decal to be a simple plane, it's performance friendly"), planarMeshDecals); EditorGUILayout.Separator(); decal.scaleRange = EditorGUILayout.Vector2Field(new GUIContent("Scale range", "Randomize decal scale between 2 values"), decal.scaleRange, new GUILayoutOption[] { GUILayout.Width(0.5f * position.width) }); decal.scaleRange.x = Mathf.Clamp(decal.scaleRange.x, 0.01f, 10); decal.scaleRange.y = Mathf.Clamp(decal.scaleRange.y, 0.01f, 10); EditorGUILayout.Separator(); decal.rotationRange = EditorGUILayout.Vector2Field(new GUIContent("Rotation range", "Randomize decal rotation between 2 values"), decal.rotationRange, new GUILayoutOption[] { GUILayout.Width(0.5f * position.width) }); decal.rotationRange.x = Mathf.Clamp(decal.rotationRange.x, 0, 360); decal.rotationRange.y = Mathf.Clamp(decal.rotationRange.y, 0, 360); } else { decal.lockedShapeAlways = EditorGUILayout.Toggle(new GUIContent("Lock shape always", "Lock shape always"), decal.lockedShapeAlways); decal.lockedShapeInRuntime = EditorGUILayout.Toggle(new GUIContent("Lock shape in runtime", "Lock shape in runtime"), decal.lockedShapeInRuntime); decal.planarDecal = EditorGUILayout.Toggle(new GUIContent("A Simple planar", "Do the decal to be a simple plane, it's performance friendly"), decal.planarDecal); EditorGUILayout.Separator(); } EditorGUILayout.Separator(); decal.angleLimit = EditorGUILayout.Slider(new GUIContent("Collision angle limit", "For not planar decals, max angle between hit objects"), decal.angleLimit, 1, 180); decal.angleLimit = Mathf.Clamp(decal.angleLimit, 1, 180); decal.distanceFromHit = EditorGUILayout.Slider(new GUIContent("Distance from hit", "Distance in the hit normal from hit object"), decal.distanceFromHit, 0.001f, 1); decal.distanceFromHit = Mathf.Clamp(decal.distanceFromHit, 0.001f, 1); EditorGUILayout.Separator(); EditorGUILayout.Separator(); } EditorBasicFunctions.DrawEditorBox("Choose mesh decal!", Color.white, position); EditorGUILayout.Separator(); EditorGUILayout.Separator(); decal.material = EditorBasicFunctions.ShowObjectField <Material> ("Actual selected material ", decal.material); decal.material = EditorBasicFunctions.DrawMeshDecalMaterialList(decal.material, Screen.width); EditorGUILayout.Separator(); EditorGUILayout.Separator(); if (decal.material) { List <Sprite> spriteListFromTexture = EditorBasicFunctions.GetSpriteListFromTexture(decal.material.mainTexture); if (spriteListFromTexture.Count > 0) { decal.sprite = spriteListFromTexture [0]; } if (!comeFromEditor) { //EditorGUILayout.Separator (); //EditorGUILayout.Separator (); EditorBasicFunctions.DrawEditorBox("Info", Color.white, position); //decal.affectedLayers = EditorBasicFunctions.LayerMaskField ("Affected Layers", decal.affectedLayers); decal.showAffectedObject = EditorGUILayout.Foldout(decal.showAffectedObject, "Affected Objects"); if (decal.showAffectedObject && (decal.affectedObjects != null)) { GUILayout.BeginHorizontal(); GUILayout.Space(15); GUILayout.BeginVertical(); foreach (GameObject go in decal.affectedObjects) { EditorGUILayout.ObjectField(go, typeof(GameObject), true); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } EditorGUILayout.Separator(); } return(decal.material); } } return(null); }
/////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// BuildDecalForObject /// # Build a decal for one of the affected objects /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////// public static void BuildDecalForObject(GenericMeshDecal decal, GameObject affectedObject) { if (affectedObject.isStatic) { Debug.Log("NOTE: static objects are not supported by realtime mesh decals, we are trying to make it possible soon"); } else { Mesh affectedMesh = affectedObject.GetComponent <MeshFilter> ().sharedMesh; if (affectedMesh == null) { return; } float angleLimit = decal.angleLimit; Plane right = new Plane(Vector3.right, Vector3.right / 2f); Plane left = new Plane(-Vector3.right, -Vector3.right / 2f); Plane top = new Plane(Vector3.up, Vector3.up / 2f); Plane bottom = new Plane(-Vector3.up, -Vector3.up / 2f); Plane front = new Plane(Vector3.forward, Vector3.forward / 2f); Plane back = new Plane(-Vector3.forward, -Vector3.forward / 2f); Vector3[] vertices = affectedMesh.vertices; int[] triangles = affectedMesh.triangles; int startVertexCount = vertexBufferList.Count; Matrix4x4 matrix = decal.transform.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix; for (int i = 0; i < triangles.Length; i += 3) { int i1 = triangles [i]; int i2 = triangles [i + 1]; int i3 = triangles [i + 2]; Vector3 v1 = matrix.MultiplyPoint(vertices [i1]); Vector3 v2 = matrix.MultiplyPoint(vertices [i2]); Vector3 v3 = matrix.MultiplyPoint(vertices [i3]); Vector3 side1 = v2 - v1; Vector3 side2 = v3 - v1; Vector3 normal = Vector3.Cross(side1, side2).normalized; if (Vector3.Angle(-Vector3.forward, normal) >= angleLimit) { continue; } GenericPoly poly = new GenericPoly(v1, v2, v3); poly = GenericPoly.ClipPoly(poly, right); if (poly == null) { continue; } poly = GenericPoly.ClipPoly(poly, left); if (poly == null) { continue; } poly = GenericPoly.ClipPoly(poly, top); if (poly == null) { continue; } poly = GenericPoly.ClipPoly(poly, bottom); if (poly == null) { continue; } poly = GenericPoly.ClipPoly(poly, front); if (poly == null) { continue; } poly = GenericPoly.ClipPoly(poly, back); if (poly == null) { continue; } AddPoly(poly, normal); } GenerateTexCoords(startVertexCount, decal.sprite); } }