static void _getWallsByMaxArea(List <MeshCollider> getReconColliderList, out List <MeshSizeData> meshSizeDataList, out List <MeshCollider> ignoreList) { //SRWorkControl.Instance.GetReconstructStaticConvexCollider(out getReconColliderList); //SRWorkControl.Instance.GetReconstructStaticQuadCollider(); ignoreList = new List <MeshCollider>(); meshSizeDataList = new List <MeshSizeData>(); List <MeshCollider> .Enumerator itr = getReconColliderList.GetEnumerator(); while (itr.MoveNext()) { Vector3[] triNormal; //Ignore normal dot with up is near 0 (near 1 is wall, near 0 is ground) Vector3 normalLocal = _getAVGNormalLocal(itr.Current.sharedMesh, itr.Current.transform, out triNormal); Vector3 AVGNormalWorld = (normalLocal); //float dot = Vector3.Dot(Vector3.up, AVGNormalWorld); //if (-0.3f < dot && dot < 0.3f) float angle = Vector3.Angle(Vector3.up, AVGNormalWorld); //ignore not vertical with floor if (90 - 30 > angle || angle > 90 + 30) { ignoreList.Add(itr.Current); continue; } //ignore not face to player Vector3 meshCenter = itr.Current.transform.TransformPoint(_getMeshCenter(itr.Current.sharedMesh)); Vector3 faceToNormal = GameManager.Instance.GetFaceToPlayerNormal(meshCenter, AVGNormalWorld); Vector3 dir2Player = ARRender.Instance.VRCamera.transform.position - meshCenter; angle = Vector3.Angle(dir2Player, faceToNormal); if (angle > 70) { ignoreList.Add(itr.Current); continue; } #if UNITY_EDITOR Debug.DrawLine(meshCenter, meshCenter + AVGNormalWorld * 2, Color.red); #endif MeshSizeData data = new MeshSizeData(); data.area = GetMeshArea(itr.Current.sharedMesh); data.meshCenterWorld = meshCenter; data.colliderMesh = itr.Current; data.avgNormalWorld = AVGNormalWorld; data.triNormal = triNormal; meshSizeDataList.Add(data); } meshSizeDataList.Sort(); }
static void _getPlanesByMaxArea(List <MeshCollider> getReconColliderList, out List <MeshSizeData> meshSizeDataList, out List <MeshCollider> ignoreList) { ignoreList = new List <MeshCollider>(); meshSizeDataList = new List <MeshSizeData>(); List <MeshCollider> .Enumerator itr = getReconColliderList.GetEnumerator(); while (itr.MoveNext()) { /* * Vector3[] triNormal; * //Ignore normal dot with up is near 0 (near 1 is wall, near 0 is ground) * Vector3 normalLocal = _getAVGNormalLocal(itr.Current.sharedMesh, itr.Current.transform, out triNormal); * Vector3 AVGNormalWorld = (normalLocal); * //float dot = Vector3.Dot(Vector3.up, AVGNormalWorld); * //if (-0.3f < dot && dot < 0.3f) * float angle = Vector3.Angle(Vector3.up, AVGNormalWorld); * //ignore not correspond with floor * if (-20 > angle || angle > 20) * { * ignoreList.Add(itr.Current); * continue; * } */ ////ignore not face to player Vector3 meshCenter = itr.Current.transform.TransformPoint(_getMeshCenter(itr.Current.sharedMesh)); //Vector3 dir2Player = VRCamera.transform.position - meshCenter; //angle = Vector3.Angle(dir2Player, AVGNormalWorld); //if (Vector3.Dot(dir2Player, AVGNormalWorld) < 0) ////if(angle > 40) //{ // ignoreList.Add(itr.Current); // continue; //} MeshSizeData data = new MeshSizeData(); data.area = GetMeshArea(itr.Current.sharedMesh); data.meshCenterWorld = meshCenter; data.colliderMesh = itr.Current; data.avgNormalWorld = Vector3.zero; //AVGNormalWorld; data.triNormal = null; //triNormal; meshSizeDataList.Add(data); } meshSizeDataList.Sort(); }
public void AutoPickFloor() { List <MeshSizeData> meshSizeDataList; List <MeshCollider> ignoreList; _getPlanesByMaxArea(reconstructConvexCollidersHorizontal, out meshSizeDataList, out ignoreList); //if (recontructTable != null) // Destroy(recontructTable); //recontructTable = new GameObject("RecontructTable"); if (recontructFloor != null) { Destroy(recontructFloor); } recontructFloor = new GameObject("RecontructFloor"); if (floorPlaneObj != null) { Destroy(floorPlaneObj); } if (floorPlaneObjCollider != null) { Destroy(floorPlaneObjCollider); } //Get the lowest is the floor and y must -0.5~0.5 MeshSizeData lowestMesh = null; float lowestD = 9999f; for (int a = 0; a < meshSizeDataList.Count; a++) { if (a >= 3) { break; } MeshSizeData current = meshSizeDataList[a]; if (current.meshCenterWorld.y < lowestD) { //if (-0.6f < current.meshCenterWorld.y && current.meshCenterWorld.y < 0.6f) { lowestD = current.meshCenterWorld.y; lowestMesh = current; } } } if (lowestMesh != null) { GameObject floorConvexObj = SetPivotInMeshCenter( lowestMesh.colliderMesh.transform, lowestMesh.colliderMesh.sharedMesh, recontructFloor.transform, null, lowestMesh.colliderMesh.name + "_convex : " + lowestMesh.area, lowestMesh.avgNormalWorld, lowestMesh.meshCenterWorld); meshSizeDataList.Remove(lowestMesh); //Add floor quad for shadow rendering foreach (MeshCollider mc in reconstructQuadCollidersHorizontal) { string namesQuad = mc.name.Remove(0, mc.name.IndexOf('_') + 1); string namesConvex = lowestMesh.colliderMesh.name.Remove(0, lowestMesh.colliderMesh.name.IndexOf('_') + 1); if (namesQuad == namesConvex) { //Vector3[] planeTriNormal; //Vector3 AVGNormalWorld = -_getAVGNormalLocal(mc.sharedMesh, mc.transform, out planeTriNormal); Vector3 center = mc.transform.TransformPoint(_getMeshCenter(mc.sharedMesh)); //GameObject floorPlaneObj = SetPivotInMeshCenter(mc.transform, mc.sharedMesh, // floorConvexObj.transform, floorColliderMaterial, // lowestMesh.colliderMesh.name + "_quadFloor", // AVGNormalWorld, center); floorPlaneObj = GameObject.CreatePrimitive(PrimitiveType.Plane); floorPlaneObj.name = lowestMesh.colliderMesh.name + "_quadFloor"; floorPlaneObj.transform.parent = floorConvexObj.transform; floorPlaneObj.transform.position = center; floorPlaneObj.transform.rotation = Quaternion.identity; floorPlaneObj.transform.localScale = Vector3.one * 2; //SRWork 0.7.5.0 use scan mesh collider floorPlaneObj.isStatic = true; floorPlaneObj.layer = AdvanceRender.ScanLiveMeshLayer; if (ARRender.ADVANCE_RENDER) { //In advance render floorPlaneObj is for render, so, we clone a new one for collision floorPlaneObjCollider = GameObject.Instantiate(floorPlaneObj); floorPlaneObjCollider.layer = AdvanceRender.MRCollisionFloorLayer; floorPlaneObjCollider.transform.position = floorPlaneObj.transform.position; floorPlaneObjCollider.transform.rotation = floorPlaneObj.transform.rotation; ARRender.Instance.VRCamera.cullingMask = MyHelpLayer.RemoveMaskLayer(ARRender.Instance.VRCamera.cullingMask, AdvanceRender.MRCollisionFloorLayer); } else { floorPlaneObj.GetComponent <MeshRenderer>().sharedMaterial = new Material(Shader.Find("ViveSR/MeshCuller, Shadowed, Stencil")); //floorPlaneObj.GetComponent<MeshRenderer>().enabled = false; } break; } } //SRWork0.7.5.0 ConvexColliders default is turn off //turn off the original convex mesh's collider //foreach (MeshCollider mc in reconstructConvexCollidersHorizontal) //{ // string namesA = mc.name.Remove(0, mc.name.IndexOf('_') + 1); // string namesB = lowestMesh.colliderMesh.name.Remove(0, lowestMesh.colliderMesh.name.IndexOf('_') + 1); // //namesA = namesA.Remove(0, namesA.IndexOf('_'));//srwork 0.7 without '_' again // //namesB = namesB.Remove(0, namesB.IndexOf('_')); // if (namesA == namesB) // { // mc.transform.gameObject.SetActive(false); // } //} } else { Debug.LogWarning("[reconstructPickFloor] there are no reconstruct floor picked..."); } /* * //Get the highest is the table * MeshSizeData highestMesh = null; * float highestD = -9999f; * for (int a = 0; a < meshSizeDataList.Count; a++) * { * if (a >= 10) * break; * MeshSizeData current = meshSizeDataList[a]; * if (current.meshCenterWorld.y > highestD && * current.meshCenterWorld.y < VRCamera.transform.position.y//must not higher then player's head * ) * { * highestD = current.meshCenterWorld.y; * highestMesh = current; * } * } * if (highestMesh != null) * { * SetPivotInMeshCenter(highestMesh.colliderMesh.transform, highestMesh.colliderMesh.sharedMesh, * recontructTable.transform, tableColliderMaterial, * highestMesh.colliderMesh.name + "_convex : " + highestMesh.area, * highestMesh.avgNormalWorld, * highestMesh.meshCenterWorld); * meshSizeDataList.Remove(highestMesh); * } * else * Debug.LogWarning("[reconstructPickFloor] there are no reconstruct table picked..."); */ }