void OnDrawGizmosSelected() { // Draw World Space Origin Gizmos.DrawWireCube(Vector3.zero, new Vector3(100, 100, 100)); switch (gizmosDrawType) { case GizmosDrawType.GizmosDrawTypeCameraInLeaf: // Draw the leaf which camera in side GizmosDrawCameraInsideLeaf(Camera.main); break; case GizmosDrawType.GizmosDrawTypeFrustumCulling: // Draw camera frustum culling process UnityEngine.Bounds[] bs = new UnityEngine.Bounds[lastVisibleLeafs.Count]; for (int i = 0; i < bs.Length; i++) { BSPFileParser.BSPTreeLeaf leaf = _leafs[i]; Bounds b = new Bounds(); b.SetMinMax(new Vector3(leaf.mins[0], leaf.mins[1], leaf.mins[2]), new Vector3(leaf.maxs[0], leaf.maxs[1], leaf.maxs[2])); b = Right2Left(b); bs[i] = b; } GizmosDrawCameraFrustum(Camera.main, Color.green); GizmosDrawFrustumCulling(Camera.main, Color.yellow, bs); break; case GizmosDrawType.GizmosDrawTypeAllLeaves: GizmosDrawAllLeaves(); break; } }
void GizmosDrawABrushOfLeaf(int brushIndex) { Color tc = Gizmos.color; // Draw Brush Gizmos.color = Color.white; BSPFileParser.Brush bsh = _brushes[brushIndex]; for (int k = bsh.brushside; k < bsh.brushside + bsh.n_brushsides; k++) { BSPFileParser.Brushside bsd = _brushsides[k]; UnityEngine.Plane plane = planes[bsd.plane]; GizmosDrawPlane(GetOnePointOnPlane(plane), plane.normal, 5000.0f); } // Draw Leaf which hold the brushIndex Gizmos.color = Color.red; for (int i = 0; i < _leafs.Length; i++) { BSPFileParser.BSPTreeLeaf lf = _leafs[i]; for (int j = lf.leafbrush; j < lf.leafbrush + lf.n_leafbrushes; j++) { if (_leafbrushes[j] == brushIndex) { Bounds temp = new Bounds(); temp.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); temp = Right2Left(temp); Gizmos.DrawWireCube(temp.center, temp.size); } } } Gizmos.color = tc; }
ArrayList frustumCulling(Camera cam, ArrayList visibleLeafs) { ArrayList visible = new ArrayList(); UnityEngine.Plane[] cameraPlanes = GeometryUtility.CalculateFrustumPlanes(cam); foreach (int i in visibleLeafs) { BSPFileParser.BSPTreeLeaf lf = _leafs[i]; Bounds b = new Bounds(); b.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); // Notice: Convert Bounding-Box from right hand coordinate into left coordinate b = Right2Left(b); if (GeometryUtility.TestPlanesAABB(cameraPlanes, b)) { visible.Add(i); } // May be use above BSP Bounding Box can avoid Unity to calculate bounds //if (GeometryUtility.TestPlanesAABB(cameraPlanes, objects[i].GetComponent<MeshRenderer>().bounds)) { // visible.Add(i); //} } return(visible); }
ArrayList frustumCulling(Camera cam, ArrayList visibleLeafs) { // Frustum Culling to reduce the number of visible leaves ArrayList visible = new ArrayList(); UnityEngine.Plane[] cameraPlanes = GeometryUtility.CalculateFrustumPlanes(cam); foreach (int i in visibleLeafs) { BSPFileParser.BSPTreeLeaf lf = _leafs[i]; Bounds b = new Bounds(); b.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); // Notice: Convert Bounding-Box from right hand coordinate into left coordinate b = Right2Left(b); if (GeometryUtility.TestPlanesAABB(cameraPlanes, b)) { visible.Add(i); } // Abandoned legacy //for(int face = lf.leafface; face<lf.leafface+lf.n_leaffaces; face++) { // int faceIndex = _leaffaces[face]; // if(GeometryUtility.TestPlanesAABB(cameraPlanes, objects[faceIndex].GetComponent<MeshCollider>().bounds)) { // visible.Add(i); // // if any of leaf's face is visible, meaning the leaf is visible(no need to check other faces) // break; // } //} } return(visible); }
void GizmosDrawLeaves(int whichLeaf) { Color tc = Gizmos.color; if (whichLeaf >= 0) { BSPFileParser.BSPTreeLeaf lf = _leafs[whichLeaf]; Bounds temp = new Bounds(); temp.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); temp = Right2Left(temp); Gizmos.color = Color.white; Gizmos.DrawWireCube(temp.center, temp.size); Gizmos.color = tc; return; } // Draw all of leaves for (int i = 0; i < _leafs.Length; i++) { BSPFileParser.BSPTreeLeaf lf = _leafs[i]; Bounds temp = new Bounds(); temp.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); temp = Right2Left(temp); Gizmos.color = Color.white; Gizmos.DrawWireCube(temp.center, temp.size); } Gizmos.color = tc; }
void LoadCollider(GameObject gmObject) { for (int i = 0; i < _leafs.Length; i++) { for (int j = _leafs[i].leafbrush; j < _leafs[i].leafbrush + _leafs[i].n_leafbrushes; j++) { int brushIndex = _leafbrushes[j]; BSPFileParser.Brush bsh = _brushes[brushIndex]; if (bsh.n_brushsides == 6) { // Generate Box Collider directly by the 6 bounding planes UnityEngine.Plane[] ps = new UnityEngine.Plane[bsh.n_brushsides]; for (int k = bsh.brushside; k < bsh.brushside + bsh.n_brushsides; k++) { UnityEngine.Plane plane = planes[_brushsides[k].plane]; ps[k - bsh.brushside] = new UnityEngine.Plane(plane.normal, plane.distance); } Bounds b = GenerateBoxFromPlanes(ps); GameObject obj = new GameObject(); obj.name = "BoxCollider"; obj.AddComponent <BoxCollider>(); obj.GetComponent <BoxCollider>().center = b.center; obj.GetComponent <BoxCollider>().size = b.size; obj.transform.SetParent(gmObject.transform); } else { // Generate Box Collider by leaf bounding box which brush in it for (int m = 0; m < _leafs.Length; m++) { BSPFileParser.BSPTreeLeaf lf = _leafs[m]; for (int n = lf.leafbrush; n < lf.leafbrush + lf.n_leafbrushes; n++) { if (_leafbrushes[n] == brushIndex) { Bounds b = new Bounds(); b.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); b = Right2Left(b); GameObject obj = new GameObject(); obj.name = "BoxCollider"; obj.AddComponent <BoxCollider>(); obj.GetComponent <BoxCollider>().center = b.center; obj.GetComponent <BoxCollider>().size = b.size; obj.transform.SetParent(gmObject.transform); } } } } } } }
void GizmosDrawCameraInsideLeaf(Camera cam) { Color tc = Gizmos.color; Color[] cs = new Color[] { Color.gray, Color.yellow, Color.magenta, Color.red }; // from light to dark int colorIndex = 0; Vector3 position = cam.transform.position; // Camera Gizmos.DrawCube(position, new Vector3(200, 200, 200)); int index = 0; while (index >= 0) { Gizmos.color = cs[colorIndex++ % cs.Length]; BSPFileParser.BSPTreeNode node = _nodes[index]; UnityEngine.Plane plane = planes[node.plane]; Bounds b = new Bounds(); b.SetMinMax(new Vector3(node.mins[0], node.mins[1], node.mins[2]), new Vector3(node.maxs[0], node.maxs[1], node.maxs[2])); b = Right2Left(b); // Draw Sub-Space(BSP Tree Node bounding box) Gizmos.DrawWireCube(b.center, b.size); // Draw Split-Plane GizmosDrawPlane(GetOnePointOnPlane(plane), plane.normal, 5000.0f); if (plane.GetSide(position)) { index = node.children[0]; //Debug.Log("Front"); } else { index = node.children[1]; //Debug.Log("Back"); } } // Draw BSP Tree Leaf bounding box BSPFileParser.BSPTreeLeaf lf = _leafs[-index - 1]; Bounds temp = new Bounds(); temp.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); temp = Right2Left(temp); Gizmos.color = Color.white; Gizmos.DrawWireCube(temp.center, temp.size); Gizmos.color = tc; }
ArrayList occlusionCulling(int cluster) { ArrayList visibleLeafs = new ArrayList(); for (int i = 0; i < _leafs.Length; i++) { BSPFileParser.BSPTreeLeaf lf = _leafs [i]; if (isClusterVisible(cluster, lf.cluster)) { visibleLeafs.Add(i); } } return(visibleLeafs); }
void GizmosDrawAllOfLeavesSpace() { // Draw All Of BSP Tree Leafs bounding box Color temp = Gizmos.color; Gizmos.color = Color.white; for (int i = 0; i < _leafs.Length; i++) { BSPFileParser.BSPTreeLeaf leaf = _leafs[i]; Bounds b = new Bounds(); b.SetMinMax(new Vector3(leaf.mins[0], leaf.mins[1], leaf.mins[2]), new Vector3(leaf.maxs[0], leaf.maxs[1], leaf.maxs[2])); b = Right2Left(b); Gizmos.DrawWireCube(b.center, b.size); } }
void GizmosDrawLeafBrushes(int whichLeaf) { Color tc = Gizmos.color; Color[] cs = new Color[] { Color.gray, Color.yellow, Color.magenta, Color.red }; // from light to dark int colorIndex = 0; if (whichLeaf >= 0) { BSPFileParser.BSPTreeLeaf lf = _leafs[whichLeaf]; for (int j = lf.leafbrush; j < lf.leafbrush + lf.n_leafbrushes; j++) { int brushIndex = _leafbrushes[j]; BSPFileParser.Brush bsh = _brushes[brushIndex]; Gizmos.color = cs[colorIndex++ % cs.Length]; for (int k = bsh.brushside; k < bsh.brushside + bsh.n_brushsides; k++) { BSPFileParser.Brushside bsd = _brushsides[k]; UnityEngine.Plane plane = planes[bsd.plane]; GizmosDrawPlane(GetOnePointOnPlane(plane), plane.normal, 5000.0f); } } Gizmos.color = tc; return; } // Draw All brushes for leaves int len = _leafs.Length; for (int i = 0; i < len; i++) { BSPFileParser.BSPTreeLeaf lf = _leafs[i]; for (int j = lf.leafbrush; j < lf.leafbrush + lf.n_leafbrushes; j++) { int brushIndex = _leafbrushes[j]; BSPFileParser.Brush bsh = _brushes[brushIndex]; Gizmos.color = cs[colorIndex++ % cs.Length]; for (int k = bsh.brushside; k < bsh.brushside + bsh.n_brushsides; k++) { BSPFileParser.Brushside bsd = _brushsides[k]; UnityEngine.Plane plane = planes[bsd.plane]; GizmosDrawPlane(GetOnePointOnPlane(plane), plane.normal, 5000.0f); } } } Gizmos.color = tc; }
// Load all of meshes to construct game objects // and as children be add to gmObject void LoadAllMeshAndObject(GameObject gmObject, string childName) { gmObject.transform.DetachChildren(); int len = _leafs.Length; meshes = new UnityEngine.Mesh[len]; objects = new UnityEngine.GameObject[len]; for (int leafIndex = 0; leafIndex < len; leafIndex++) { BSPFileParser.BSPTreeLeaf lf = _leafs[leafIndex]; // Construct Mesh UnityEngine.Mesh mesh = new UnityEngine.Mesh(); mesh.vertices = vertices; mesh.normals = normals; mesh.uv = uvs; mesh.uv2 = uv2s; mesh.colors = colors; materials = new UnityEngine.Material[lf.n_leaffaces]; mesh.subMeshCount = lf.n_leaffaces; for (int leafFaceIndex = lf.leafface; leafFaceIndex < lf.leafface + lf.n_leaffaces; leafFaceIndex++) { int faceIndex = _leaffaces[leafFaceIndex]; BSPFileParser.Face f = _faces[faceIndex]; materials[leafFaceIndex - lf.leafface] = allmaterials[f.texture]; mesh.SetTriangles(triangleLists[faceIndex], leafFaceIndex - lf.leafface); } // Construct GameObject GameObject childObject = new GameObject(childName); childObject.AddComponent <MeshFilter>().mesh = mesh; childObject.AddComponent <MeshRenderer>().materials = materials; childObject.AddComponent <MeshCollider>().sharedMesh = mesh; childObject.transform.SetParent(gmObject.transform); // Cache GameObject and Mesh meshes[leafIndex] = mesh; objects[leafIndex] = childObject; } }
ArrayList frustumCulling(Camera cam, ArrayList visibleLeafs) { ArrayList visible = new ArrayList(); UnityEngine.Plane[] cameraPlanes = GeometryUtility.CalculateFrustumPlanes(cam); foreach (int i in visibleLeafs) { BSPFileParser.BSPTreeLeaf lf = _leafs[i]; for (int face = lf.leafface; face < lf.leafface + lf.n_leaffaces; face++) { int faceIndex = _leaffaces[face]; //if(GeometryUtility.TestPlanesAABB(cameraPlanes, objects[faceIndex].GetComponent<MeshCollider>().bounds)) { if (GeometryUtility.TestPlanesAABB(cameraPlanes, objects[faceIndex].GetComponent <MeshRenderer>().bounds)) { visible.Add(i); break; // if any of leaf's face is visible, meaning the leaf is visible(no need to check other faces) } } } return(visible); }
ArrayList frustumCulling(Camera cam, ArrayList visibleLeafs) { // Frustum Culling to reduce the number of visible leaves ArrayList visible = new ArrayList(); UnityEngine.Plane[] cameraPlanes = GeometryUtility.CalculateFrustumPlanes(cam); foreach (int i in visibleLeafs) { BSPFileParser.BSPTreeLeaf lf = _leafs[i]; Bounds b = new Bounds(); b.SetMinMax(new Vector3(lf.mins[0], lf.mins[1], lf.mins[2]), new Vector3(lf.maxs[0], lf.maxs[1], lf.maxs[2])); // Notice: Convert Bounding-Box from right hand coordinate into left coordinate b = Right2Left(b); if (GeometryUtility.TestPlanesAABB(cameraPlanes, b)) { visible.Add(i); } } return(visible); }