private static void _GetRoots(bool includeStatic, bool includeDynamic, List <Transform> rootTransforms, List <Bounds> rootBounds) { if (includeStatic || includeDynamic) { Transform[] allTransforms = (Transform[])GameObject.FindObjectsOfType(typeof(Transform)); foreach (Transform transform in allTransforms) { if (transform.parent == null && ((transform.gameObject.isStatic && includeStatic) || !transform.gameObject.isStatic && includeDynamic)) { Bounds aggregateBounds = new Bounds(); bool initBounds = false; Renderer[] childRenderers = transform.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in childRenderers) { Bounds renderBounds = renderer.bounds; // Particle bounds are unreliable in editor, so use a unit sized box as a proxy. if (renderer.GetType() == typeof(ParticleSystemRenderer) #if UNITY_OLD_PARTICLES || renderer.GetType() == typeof(ParticleRenderer) #endif ) { renderBounds = new Bounds(transform.position, Vector3.one); } if (!initBounds) { aggregateBounds = renderBounds; initBounds = true; } else { aggregateBounds.Encapsulate(renderBounds); } } Light[] childLights = transform.GetComponentsInChildren <Light>(); foreach (Light light in childLights) { if (!initBounds) { aggregateBounds = SECTR_Geometry.ComputeBounds(light); initBounds = true; } else { aggregateBounds.Encapsulate(SECTR_Geometry.ComputeBounds(light)); } } if (initBounds) { rootTransforms.Add(transform); rootBounds.Add(aggregateBounds); } ; } } } }
protected void _EditHull(SECTR_Hull myHull) { HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); if (Event.current.type == EventType.MouseMove) { _ComputeCursorVert(); closesetVertIsValid = true; if (newHullVerts.Count > 2) { Vector3 firstVert = newHullVerts[0]; if (Vector3.SqrMagnitude(closestVert - firstVert) < SECTR_Geometry.kVERTEX_EPSILON) { closestVert = firstVert; closesetVertIsValid = true; } else { Plane hullPlane = new Plane(newHullVerts[0], newHullVerts[1], newHullVerts[2]); closesetVertIsValid = hullPlane.GetDistanceToPoint(closestVert) < SECTR_Geometry.kVERTEX_EPSILON; if (closesetVertIsValid) { List <Vector3> newVerts = new List <Vector3>(newHullVerts); newVerts.Add(closestVert); closesetVertIsValid = SECTR_Geometry.IsPolygonConvex(newVerts.ToArray()); } } } } else if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && !Event.current.alt && !Event.current.control) { if (closesetVertIsValid) { if (!newHullVerts.Contains(closestVert)) { newHullVerts.Add(closestVert); } else if (newHullVerts.Count >= 3) { _CompleteHull(myHull); HandleUtility.Repaint(); } } } else if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Return) { if (newHullVerts.Count >= 3 || (myHull.ForceEditHull && newHullVerts.Count == 0)) { _CompleteHull(myHull); HandleUtility.Repaint(); } } else if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Escape) { _EndNewHull(myHull, true); } }
private SECTR_Chunk _GetOppositeChunk(Vector3 position) { if (Portal) { SECTR_Sector oppositeSector = SECTR_Geometry.IsPointInFrontOfPlane(position, Portal.Center, Portal.Normal) ? Portal.BackSector : Portal.FrontSector; if (oppositeSector) { return(oppositeSector.GetComponent <SECTR_Chunk>()); } } return(null); }
private static void _Encapsulate(SECTR_Sector newSector, List <Transform> rootTransforms, List <Bounds> rootBounds, string undoString) { int numRoots = rootTransforms.Count; for (int rootIndex = numRoots - 1; rootIndex >= 0; --rootIndex) { Transform rootTransform = rootTransforms[rootIndex]; if (rootTransform != newSector.transform && SECTR_Geometry.BoundsContainsBounds(newSector.TotalBounds, rootBounds[rootIndex])) { SECTR_Undo.Parent(newSector.gameObject, rootTransform.gameObject, undoString); rootTransforms.RemoveAt(rootIndex); rootBounds.RemoveAt(rootIndex); } } }
public List <SECTR_Member.Child> GetSharedChildren() { List <SECTR_Member.Child> sharedChildren = new List <SECTR_Member.Child>(); List <SECTR_Sector> overlappingSectors = new List <SECTR_Sector>(); int numChildren = Children.Count; for (int childIndex = 0; childIndex < numChildren; ++childIndex) { SECTR_Member.Child child = Children[childIndex]; if (child.renderer && !SECTR_Geometry.BoundsContainsBounds(TotalBounds, child.rendererBounds)) { GetContaining(ref overlappingSectors, child.rendererBounds); if (overlappingSectors.Count > 1) { sharedChildren.Add(child); continue; } } if (child.light && !SECTR_Geometry.BoundsContainsBounds(TotalBounds, child.lightBounds)) { GetContaining(ref overlappingSectors, child.lightBounds); if (overlappingSectors.Count > 1) { sharedChildren.Add(child); continue; } } if (child.terrain && !SECTR_Geometry.BoundsContainsBounds(TotalBounds, child.terrainBounds)) { GetContaining(ref overlappingSectors, child.terrainBounds); if (overlappingSectors.Count > 1) { sharedChildren.Add(child); continue; } } } return(sharedChildren); }
public void Init(GameObject gameObject, Renderer renderer, Light light, Terrain terrain, SECTR_Member member, bool dirShadowCaster, Vector3 shadowVec) { this.gameObject = gameObject; this.gameObjectHash = this.gameObject.GetInstanceID(); this.member = member; this.renderer = renderer && (renderCulled || renderer.enabled) ? renderer : null; this.light = (light && (lightCulled || light.enabled) && (light.type == LightType.Point || light.type == LightType.Spot)) ? light : null; this.terrain = (terrain && (terrainCulled || terrain.enabled)) ? terrain : null; rendererBounds = this.renderer ? this.renderer.bounds : new Bounds(); lightBounds = this.light ? SECTR_Geometry.ComputeBounds(this.light) : new Bounds(); terrainBounds = this.terrain ? SECTR_Geometry.ComputeBounds(this.terrain) : new Bounds(); layer = gameObject.layer; if (SECTR_Modules.VIS) { this.renderHash = this.renderer ? this.renderer.GetInstanceID() : 0; this.lightHash = this.light ? this.light.GetInstanceID() : 0; this.terrainHash = this.terrain ? this.terrain.GetInstanceID() : 0; bool liveLightmaps; #if UNITY_4 liveLightmaps = LightmapSettings.lightmapsMode == LightmapsMode.Dual; #else liveLightmaps = true; #endif #if UNITY_2017_3_OR_NEWER shadowLight = this.light && light.shadows != LightShadows.None && (!light.bakingOutput.isBaked || liveLightmaps); #elif UNITY_5_4_OR_NEWER shadowLight = this.light && light.shadows != LightShadows.None && (!light.isBaked || liveLightmaps); #elif UNITY_4_0 || UNITY_4_1 shadowLight = this.light && light.shadows != LightShadows.None; #else shadowLight = this.light && light.shadows != LightShadows.None && (!light.alreadyLightmapped || liveLightmaps); #endif #if UNITY_4 rendererCastsShadows = this.renderer && renderer.castShadows && (renderer.lightmapIndex == -1 || liveLightmaps); #else rendererCastsShadows = this.renderer && renderer.shadowCastingMode != UnityEngine.Rendering.ShadowCastingMode.Off && (renderer.lightmapIndex == -1 || liveLightmaps); #endif terrainCastsShadows = this.terrain && terrain.castShadows && (terrain.lightmapIndex == -1 || liveLightmaps); if (dirShadowCaster) { if (rendererCastsShadows) { rendererBounds = SECTR_Geometry.ProjectBounds(rendererBounds, shadowVec); } if (terrainCastsShadows) { terrainBounds = SECTR_Geometry.ProjectBounds(terrainBounds, shadowVec); } } if (shadowLight) { shadowLightPosition = light.transform.position; shadowLightRange = light.range; shadowLightType = light.type; shadowCullingMask = light.cullingMask; } else { shadowLightPosition = Vector3.zero; shadowLightRange = 0; shadowLightType = LightType.Area; shadowCullingMask = 0; } } else { this.renderHash = 0; this.lightHash = 0; this.terrainHash = 0; shadowLight = false; rendererCastsShadows = false; terrainCastsShadows = false; shadowLightPosition = Vector3.zero; shadowLightRange = 0; shadowLightType = LightType.Area; shadowCullingMask = 0; } processed = true; }
// Transforms the data in HullMesh into a linear list of vertices, // computes other mesh based data, and checks for convexity and planarity. protected void ComputeVerts() { if (HullMesh != previousMesh) { if (HullMesh) { int numVerts = HullMesh.vertexCount; vertsCW = new Vector3[numVerts]; // Compute the hull centroid and initialize the CW verts array. meshCentroid = Vector3.zero; for (int vertIndex = 0; vertIndex < numVerts; ++vertIndex) { Vector3 vertex = HullMesh.vertices[vertIndex]; vertsCW[vertIndex] = vertex; meshCentroid += vertex; } meshCentroid /= HullMesh.vertexCount; // Compute the hull normal meshNormal = Vector3.zero; int numNormals = HullMesh.normals.Length; for (int normalIndex = 0; normalIndex < numNormals; ++normalIndex) { meshNormal += HullMesh.normals[normalIndex]; } meshNormal /= HullMesh.normals.Length; meshNormal.Normalize(); // Project the points onto a perfect plane and determine if the mesh is non-planar. bool meshIsPlanar = true; for (int vertIndex = 0; vertIndex < numVerts; ++vertIndex) { Vector3 vertex = vertsCW[vertIndex]; Vector3 projectedVert = vertex - Vector3.Dot(vertex - meshCentroid, meshNormal) * meshNormal; meshIsPlanar = meshIsPlanar && Vector3.SqrMagnitude(vertex - projectedVert) < SECTR_Geometry.kVERTEX_EPSILON; vertsCW[vertIndex] = projectedVert; } if (!meshIsPlanar) { Debug.LogWarning("Occluder mesh of " + name + " is not planar!"); } // Reorder the verts to be clockwise about the normal Array.Sort(vertsCW, delegate(Vector3 a, Vector3 b) { return(SECTR_Geometry.CompareVectorsCW(a, b, meshCentroid, meshNormal) * -1); }); if (!SECTR_Geometry.IsPolygonConvex(vertsCW)) { Debug.LogWarning("Occluder mesh of " + name + " is not convex!"); } } else { meshNormal = Vector3.zero; meshCentroid = Vector3.zero; vertsCW = null; } previousMesh = HullMesh; } }