public static FloorplanClick OnFloorplanSelectionClick(Building building, Ray mouseRay, bool includeInterior = false) { FloorplanClick output = new FloorplanClick(); float nearestPointDistance = Mathf.Infinity; Vector3 basePosition = building.transform.position; Quaternion baseRotation = Quaternion.Inverse(building.transform.rotation); int floorplanCount = building.numberOfPlans; for (int f = 0; f < floorplanCount; f++) { Volume volume = building[f] as Volume; float baseHeight = volume.baseHeight; Vector3 testPoint = basePosition + Vector3.up * baseHeight; if (Vector3.Dot(mouseRay.direction, testPoint - mouseRay.origin) < 0)//building { continue; } Plane planPlane = new Plane(Vector3.up, testPoint); float rayDistance = 0; if (planPlane.Raycast(mouseRay, out rayDistance)) { if (rayDistance < nearestPointDistance) { Vector3 clickPos = baseRotation * (mouseRay.GetPoint(rayDistance) - basePosition); Vector2Int planPos = new Vector2Int(clickPos, true); Vector2Int[] planPoints = volume.AllPoints(); if (PointInsidePoly(planPos, planPoints)) { nearestPointDistance = rayDistance; output.volume = volume; } if (includeInterior) { IFloorplan[] intFloorplans = volume.InteriorFloorplans(); int floors = intFloorplans.Length; for (int fl = 0; fl < floors; fl++) { Floorplan intFl = intFloorplans[fl] as Floorplan; Room[] rooms = intFl.AllRooms(); int roomCount = rooms.Length; for (int rm = 0; rm < roomCount; rm++) { Vector2Int[] roomPoints = rooms[rm].AllPoints(); if (PointInsidePoly(planPos, roomPoints)) { nearestPointDistance = rayDistance; output.volume = volume; output.floorplan = intFl; output.room = rooms[rm]; } } } } } } } return(output); }
// _drag = Drag2D(_drag, r); // // if (_mPrevRender == null) // _mPrevRender = new PreviewRenderUtility(); // // // Vector3 max = _wallSection.previewMesh.bounds.size; // // float radius = Mathf.Max(max.x, Mathf.Max(max.y, max.z)) * 1.333f; // float dist = radius / (Mathf.Sin(_mPrevRender.camera.fieldOfView * Mathf.Deg2Rad)); // _mPrevRender.camera.transform.position = Vector2.zero; // _mPrevRender.camera.transform.rotation = Quaternion.Euler(new Vector3(-_drag.y, -_drag.x, 0)); // _mPrevRender.camera.transform.position = _mPrevRender.camera.transform.forward * -dist; // _mPrevRender.camera.nearClipPlane = 0.1f; // _mPrevRender.camera.farClipPlane = 500; // // _mPrevRender.lights[0].intensity = 0.5f; // _mPrevRender.lights[0].transform.rotation = Quaternion.Euler(30f, 30f, 0f); // _mPrevRender.lights[1].intensity = 0.5f; // // _mPrevRender.BeginPreview(r, background); // // if (_plane != null && _blueprintMaterial != null) // { // Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(-25, -25, 1), Quaternion.identity, new Vector3(10, 10, 1)); // _mPrevRender.DrawMesh(_plane, matrix, _blueprintMaterial, 0); // _mPrevRender.camera.Render(); // } // // // int materialCount = mats.Length; // int submeshCount = mesh.subMeshCount; // int count = Mathf.Min(materialCount, submeshCount); // for (int c = 0; c < count; c++) // { // Material mat = c < materialCount ? mats[c] : AssetDatabase.GetBuiltinExtraResource<Material>("Default-Material.mat"); // if (mat == null) mat = AssetDatabase.GetBuiltinExtraResource<Material>("Default-Material.mat"); // _mPrevRender.DrawMesh(mesh, Matrix4x4.identity, mat, c); // } // // _mPrevRender.camera.Render(); // Texture texture = _mPrevRender.EndPreview(); // // GUI.DrawTexture(r, texture); // } // // public static Vector2 Drag2D(Vector2 scrollPosition, Rect position) // { // int controlID = GUIUtility.GetControlID("Slider".GetHashCode(), FocusType.Passive); // Event current = Event.current; // switch (current.GetTypeForControl(controlID)) // { // case EventType.MouseDown: // if (position.Contains(current.mousePosition) && position.width > 50f) // { // GUIUtility.hotControl = controlID; // current.Use(); // EditorGUIUtility.SetWantsMouseJumping(1); // } // break; // case EventType.MouseUp: // if (GUIUtility.hotControl == controlID) // { // GUIUtility.hotControl = 0; // } // EditorGUIUtility.SetWantsMouseJumping(0); // break; // case EventType.MouseDrag: // if (GUIUtility.hotControl == controlID) // { // scrollPosition -= current.delta * (float)((!current.shift) ? 1 : 3) / Mathf.Min(position.width, position.height) * 140f; // scrollPosition.y = Mathf.Clamp(scrollPosition.y, -90f, 90f); // current.Use(); // GUI.changed = true; // } // break; // } // return scrollPosition; // } public static FloorplanClick OnInteriorSelectionClick(Ray mouseRay) { FloorplanClick output = new FloorplanClick(); Building building = BuildingEditor.building; Volume volume = BuildingEditor.volume; Floorplan floorplan = BuildingEditor.floorplan; output.volume = volume; output.floorplan = floorplan; if (floorplan != null) { Vector3 basePosition = building.transform.position; float baseHeight = volume.baseHeight; Vector3 testPoint = basePosition + Vector3.up * baseHeight; if (Vector3.Dot(mouseRay.direction, testPoint - mouseRay.origin) < 0)//volume behind camera { return(output); } float floorHeight = volume.floorHeight; List <Room> rooms = floorplan.rooms; int roomCount = rooms.Count; float minDistance = Mathf.Infinity; for (int rm = 0; rm < roomCount; rm++) { Room room = rooms[rm]; RoomPortal[] portals = room.GetAllPortals(); int portalCount = portals.Length; for (int p = 0; p < portalCount; p++) { RoomPortal portal = portals[p]; int wallIndex = portal.wallIndex; Vector3 p0 = room[wallIndex].position.vector3XZ; Vector3 p1 = room[(wallIndex + 1) % room.numberOfPoints].position.vector3XZ; Vector3 baseUp = Vector3.up * (floorHeight - portal.height) * portal.verticalPosition; Vector3 portalUp = baseUp + Vector3.up * portal.height; Vector3 pointPos = SceneMeshHandler.PortalPosition(Quaternion.identity, room, portal); pointPos.y = baseHeight; Vector3 wallDirection = (p1 - p0).normalized; float defaultWidth = portal.width * 0.5f; // float defaultDepth = 0.1f; Vector3 v0 = pointPos - wallDirection * defaultWidth; Vector3 v1 = pointPos + wallDirection * defaultWidth; Vector3 v2 = v0 + portalUp; Vector3 v3 = v1 + portalUp; // Debug.DrawLine(v0,v1,Color.red,20); // Debug.DrawLine(v1,v3,Color.red,20); // Debug.DrawLine(v3,v2,Color.red,20); // Debug.DrawLine(v2,v0,Color.red,20); float distance = 0; if (RayTriangle.QuadIntersection(v0, v1, v2, v3, mouseRay, out distance, false)) { if (minDistance > distance) { minDistance = distance; output.room = room; output.portal = portal; output.opening = null; } } } } VerticalOpening[] openings = building.GetAllOpenings(); int openingCount = openings.Length; for (int o = 0; o < openingCount; o++) { VerticalOpening opening = openings[o]; Vector3 openingPosition = opening.position.vector3XZ; openingPosition.y = volume.floorHeight * opening.baseFloor; Vector3 openingSize = opening.size.vector3XZ; float openingWidth = openingSize.x; float openingHeight = openingSize.z; Quaternion openingRotation = Quaternion.Euler(0, opening.rotation, 0); Vector3 p0 = openingPosition + openingRotation * new Vector3(-openingWidth, 0, -openingHeight) * 0.5f; Vector3 p1 = openingPosition + openingRotation * new Vector3(openingWidth, 0, -openingHeight) * 0.5f; Vector3 p2 = openingPosition + openingRotation * new Vector3(openingWidth, 0, openingHeight) * 0.5f; Vector3 p3 = openingPosition + openingRotation * new Vector3(-openingWidth, 0, openingHeight) * 0.5f; // Vector3 openingUp = Vector3.up * volume.floorHeight * (opening.floors + 1); Vector3 floorUpA = Vector3.up * volume.CalculateFloorHeight(volume.Floor(BuildingEditor.floorplan)); // Vector3 floorUpB = floorUpA + Vector3.up * volume.floorHeight; float distance = 0; if (RayTriangle.QuadIntersection(p0 + floorUpA, p1 + floorUpA, p2 + floorUpA, p3 + floorUpA, mouseRay, out distance, false)) { if (minDistance > distance) { minDistance = distance; output.room = null; output.portal = null; output.opening = opening; } } } if (output.opening != null) { return(output); } if (output.portal != null) { return(output); } float intPlanBaseHeight = volume.CalculateFloorHeight(volume.Floor(floorplan)); Vector3 baseUpV = Vector3.up * intPlanBaseHeight; Plane planPlane = new Plane(Vector3.up, baseUpV); float rayDistance = 0; if (planPlane.Raycast(mouseRay, out rayDistance)) { Vector3 clickPos = mouseRay.GetPoint(rayDistance) - basePosition; Vector2Int floorClickPosition = new Vector2Int(clickPos, true); for (int rm = 0; rm < roomCount; rm++) { Vector2Int[] roomPoints = rooms[rm].AllPoints(); if (BuildrUtils.PointInsidePoly(floorClickPosition, roomPoints)) { output.room = rooms[rm]; } } } } return(output); }