/// <summary> /// Sets the material on the renderer based on the type of plane it is. /// </summary> /// <param name="plane"></param> private void SetPlaneMaterial(SurfacePlane plane) { Material mat = null; switch (plane.PlaneType) { case PlaneTypes.Ceiling: { mat = m_CeilingMaterial; break; } case PlaneTypes.Floor: { mat = m_FloorMaterial; break; } case PlaneTypes.Table: { mat = m_TableMaterial; break; } case PlaneTypes.Wall: { mat = m_WallMaterial; break; } } plane.SetPlaneMaterial(mat); }
/// <summary> /// Removes the plane from tracking. /// </summary> /// <param name="plane"></param> private void RemovePlane(SurfacePlane plane) { m_ActivePlanes.Remove(plane); switch (plane.PlaneType) { case PlaneTypes.Ceiling: { m_CeilingPlanes.Remove(plane); break; } case PlaneTypes.Floor: { m_FloorPlanes.Remove(plane); break; } case PlaneTypes.Table: { m_TablePlanes.Remove(plane); break; } case PlaneTypes.Wall: { m_WallPlanes.Remove(plane); break; } } }
/// <summary> /// A lamp will always be placed near a power oulet. /// Foreach power outlet a possible lamp position will be saved. /// </summary> /// <param name="plane">Surface plane where the power outlet is attached to.</param> /// <param name="outlet">The actual poweroutlet.</param> /// <returns></returns> private Vector3 CalculatePossibleLampPosition(Transform plane, GameObject outlet) { // If the power outlet is on the floor the potential lamp position is above it if (plane.GetComponent <SurfacePlaneExtension>().Plane.Type == PlaneTypes.Floor) { return(new Vector3(outlet.transform.position.x, outlet.transform.position.y + 1.5f, outlet.transform.position.z)); } else if (plane.GetComponent <SurfacePlaneExtension>().Plane.Type == PlaneTypes.Ceiling) // If the üpower outlet is on the ceiling the potential lamp position is below it { return(new Vector3(outlet.transform.position.x, outlet.transform.position.y - 0.5f, outlet.transform.position.z)); } else if (plane.GetComponent <SurfacePlaneExtension>().Plane.Type == PlaneTypes.Table) // If the power outlet is on a table the potential lamp position is above it { return(new Vector3(outlet.transform.position.x, outlet.transform.position.y + 0.3f, outlet.transform.position.z)); } else // If the power outlet is on a wall the potential lamp position is in front of it { //Vector3 heading = new Vector3(plane.forward.x, outlet.transform.position.y, plane.forward.z) - outlet.transform.position; SurfacePlane ceiling = converter.GetFloorOrCeiling(PlaneTypes.Ceiling); if (ceiling.Area == 0) { ceiling = converter.GetFloorOrCeiling(PlaneTypes.Floor); } Vector3 heading = new Vector3(ceiling.Bounds.Center.x, outlet.transform.position.y, ceiling.Bounds.Center.z) - outlet.transform.position; return(new Vector3(outlet.transform.position.x + (0.3f * Mathf.Sign(heading.x)), outlet.transform.position.y, outlet.transform.position.z + (0.3f * Mathf.Sign(heading.z)))); } }
// SpatialMapping pathway only public void SpawnObject(GameObject prefab, SurfacePlane plane, float localX, float localZ) { // Rotation from a coordinate system where y is up into one where z is up. // This is used to orient objects in a plane-local system before applying // the plane's own transform. Without this, objects end up aligned along // the world's xz axes, not the plane's local xy axes. Quaternion toPlaneOrientation = Quaternion.FromToRotation(Vector3.up, Vector3.forward); // World xz -> Plane xy float x = localX; float y = localZ; Vector3 origin = plane.transform.position; Quaternion rotation = plane.transform.rotation; if (plane.transform.forward.y < 0) // plane is oriented upside down { rotation = rotation * Quaternion.FromToRotation(-Vector3.forward, Vector3.forward); } // Spawn object in plane-local coordinate system (rotation brings it into world system) GameObject obj = Instantiate(prefab) as GameObject; obj.transform.parent = gameObject.transform; obj.transform.rotation = rotation * toPlaneOrientation; obj.transform.position = origin + rotation * new Vector3(x, y, 0); obj.SetActive(true); }
/// <summary> /// Displays infromation about the lighting unit on a text panel. /// </summary> public void ShowLampInformations() { title.GetComponent <TextMeshPro>().text = bulb.unitType; description.GetComponent <TextMeshPro>().text = "Light intensity (lux): " + bulb.lux + "\nDurability: " + bulb.durability + "\nWatt: " + bulb.watt + "\nEnergy consumption (watt/h per illuminated surface unit): " + (bulb.watt / (Mathf.PI * bulb.lux * bulb.lux)).ToString("F1") + " with an estimated durability of " + bulb.durability + " years"; SurfacePlane ceiling = converter.GetFloorOrCeiling(PlaneTypes.Ceiling); if (ceiling.Area == 0) { ceiling = converter.GetFloorOrCeiling(PlaneTypes.Floor); } Vector3 heading = ceiling.Bounds.Center - bulb.position; if (bulb.planeType == PlaneTypes.Ceiling) { textPanel.transform.position = new Vector3(bulb.position.x, bulb.position.y - 0.5f, bulb.position.z); } else { textPanel.transform.position = new Vector3(bulb.position.x, bulb.position.y + 0.3f, bulb.position.z); } textPanel.SetActive(true); }
public IEnumerator AttachPswToRandomPainting() { yield return(new WaitForSeconds(2f)); GameObject[] paintingsInRoom = GameObject.FindGameObjectsWithTag("Painting"); if (paintingsInRoom.Length != 0) { GameObject extractedRandomPainting = paintingsInRoom[Random.Range(0, paintingsInRoom.Length)]; GameObject newPasswordHint = Instantiate(passwordHint, extractedRandomPainting.transform.GetChild(0).transform.position, extractedRandomPainting.transform.rotation); DecorationsSpawnerManager.Instance.AddToSpawnedWallsObjects(newPasswordHint); } else //If unfortunately there are no paintings (rare case), we put the password at the center of the first wall we find { List <GameObject> walls = new List <GameObject>(); walls = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Wall); GameObject firstWall = walls[0]; SurfacePlane plane = firstWall.GetComponent <SurfacePlane>(); Vector3 positionCenterFirstWall = firstWall.GetComponent <Collider>().bounds.center + (plane.PlaneThickness * 1.01f * plane.SurfaceNormal); Quaternion rotationFirstWall = Quaternion.LookRotation(firstWall.transform.forward, Vector3.up); GameObject newPasswordHint = Instantiate(passwordHint, positionCenterFirstWall, rotationFirstWall); DecorationsSpawnerManager.Instance.AddToSpawnedWallsObjects(newPasswordHint); } }
// SpatialMapping pathway only public void DrawFloorSpawnPoints(Vector3 requiredSize, float clearance, SurfacePlane plane) { OrientedBoundingBox bb = plane.Plane.Bounds; Quaternion orientation = (plane.transform.forward.y < 0) ? (plane.transform.rotation * Quaternion.FromToRotation(-Vector3.forward, Vector3.forward)) : plane.transform.rotation; // Note that xy in local plane coordinate system correspond to what would be xz in global space Vector3 halfExtents = new Vector3(requiredSize.x, requiredSize.z, requiredSize.y) * 0.5f; for (float y = -bb.Extents.y + halfExtents.y; y <= bb.Extents.y - halfExtents.y; y += 2 * halfExtents.y) { for (float x = -bb.Extents.x + halfExtents.x; x <= bb.Extents.x - halfExtents.x; x += 2 * halfExtents.x) { Vector3 center = plane.transform.position + orientation * new Vector3(x, y, halfExtents.z + clearance); Collider[] colliders = Physics.OverlapBox(center, halfExtents, orientation, Layers.Instance.spatialMeshLayerMask); if (colliders.Length == 0) { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.parent = gameObject.transform; // level manager will be parent cube.transform.localScale = 2 * halfExtents; cube.transform.position = center; cube.transform.transform.rotation = orientation; cube.GetComponent <Renderer>().material = flatMaterial; cube.GetComponent <Renderer>().material.color = Color.green; cube.SetActive(true); } } } }
public void Embed(GameObject embedded, SurfacePlane plane) { if (null == plane) { return; } // Temporarily make the embedded object render in front of spatial mesh MakeHighPriorityRenderOrder(embedded); // Create an object describing the margin volume required for embedded // object placement GameObject marginVolume; Vector3 centerPointOnFrontPlane; Vector3 centerPointOnBackPlane; if (CreateMarginVolumeObject(out marginVolume, out centerPointOnFrontPlane, out centerPointOnBackPlane, embedded, plane)) { return; } // Deform the spatial mesh to create a margin volume large enough for the // embedded object m_requestQueue.Enqueue(new SurfacePlaneEmbedRequest(plane, m_marginByPlaneAndSpatialMesh, marginVolume, centerPointOnFrontPlane, centerPointOnBackPlane, embedded)); if (!m_working) { m_working = true; StartCoroutine(DeformSurfaceCoroutine()); } DebugVisualization(marginVolume); }
private bool placeChildOnFloor(GameObject floorPlane) { SurfacePlane surfacePlane = floorPlane.GetComponent <SurfacePlane>(); float floorYPosition = floorPlane.transform.position.y; floorY = floorYPosition; Vector3 headPosition = ScenesData.headTransform.position; //Vector3 headForward = Quaternion.Euler(-headTransform.rotation.x, 0, -headTransform.rotation.z) * headTransform.forward; ScenesData.headTransform.rotation = new Quaternion(0, ScenesData.headTransform.rotation.y, 0, 1); Vector3 headForward = ScenesData.headTransform.forward; for (float bearing = 0.0f; bearing < 360.0f; bearing += ScenesData.childStartPositionCheckAngle) { Debug.Log("Checking Bearing of: " + bearing); if (bearing != 0.0f) { headForward = Quaternion.Euler(0, ScenesData.childStartPositionCheckAngle, 0) * headForward; } Vector3 childPositionXZ = headPosition + ScenesData.childStartDistance * headForward; RaycastHit hitInfo; if (Physics.Raycast(headPosition, headForward, out hitInfo, ScenesData.childStartDistance + ScenesData.childMinDistanceToWall)) { if (debugOn) { debug_sphere(hitInfo.point, wallFailMaterial); } reveal_collider(hitInfo.collider);; Debug.Log("Raycast hits wall/object"); debug_DrawLine(headPosition, headForward, ScenesData.childStartDistance + ScenesData.childMinDistanceToWall, false); continue; } debug_DrawLine(headPosition, headForward, ScenesData.childStartDistance + ScenesData.childMinDistanceToWall, true); bool hit = Physics.Raycast(childPositionXZ, Vector3.down, out hitInfo); Vector3 directionVector = hitInfo.normal; Debug.DrawRay(hitInfo.point, directionVector, Color.blue, 100, true); if (!(hit && childPositionRayHitTest(hitInfo.point, floorYPosition))) { if (debugOn) { reveal_collider(hitInfo.collider); } debug_DrawLine(childPositionXZ, Vector3.down, headPosition.y - hitInfo.point.y, false); continue; } debug_DrawLine(childPositionXZ, Vector3.down, headPosition.y - hitInfo.point.y, true); setChildPositionAtPoint(hitInfo.point, surfacePlane); Debug.Log("SUCCESS -- CHILD POSITIONED at bearing: " + bearing); return(true); } Debug.Log("FLOOR POSITIONING FAILED"); return(false); }
public void Embed(GameObject embedded, OrientedBoundingBox obb, SurfacePlane plane, System.Action OnComplete = null, bool tempHighPriorityRender = true) { if (null == plane) { return; } // Temporarily make the embedded object render in front of spatial mesh if (tempHighPriorityRender) { MakeHighPriorityRenderOrder(embedded); } // Compute the front (pivot point of embedded object flush with surface) // and back planes of the object to be embedded Vector3 centerPointOnFrontPlane; Vector3 centerPointOnBackPlane; ComputeDepthBounds(out centerPointOnFrontPlane, out centerPointOnBackPlane, obb, embedded.transform.position, plane); // Deform the spatial mesh to create a margin volume large enough for the // embedded object m_requestQueue.Enqueue(new SurfacePlaneEmbedRequest(plane, m_marginByPlaneAndSpatialMesh, obb, centerPointOnFrontPlane, centerPointOnBackPlane, embedded, OnComplete, tempHighPriorityRender)); if (!m_working) { m_working = true; StartCoroutine(DeformSurfaceCoroutine()); } DebugVisualization(obb); }
public PowerOutlet(GameObject g, SurfacePlane p, Vector3 v, List <RaycastHit> h) { outlet = g; surfacePlane = p; lampPosition = v; hits = h; range = hits.Sum(d => d.distance); }
private void CreateBulletHole(Vector3 position, Vector3 normal, SurfacePlane plane) { GameObject bulletHole = Instantiate(m_bulletHolePrefab, position, Quaternion.LookRotation(normal)) as GameObject; bulletHole.AddComponent <WorldAnchor>(); // does this do anything? bulletHole.transform.parent = this.transform; SurfacePlaneDeformationManager.Instance.Embed(bulletHole, plane); }
private void SetPlanesVisible(bool visible) { foreach (GameObject obj in SurfaceMeshesToPlanes.Instance.ActivePlanes) { SurfacePlane plane = obj.GetComponent <SurfacePlane>(); plane.IsVisible = visible; } }
private void SetPlaneTags(string tag) { foreach (GameObject obj in SurfaceMeshesToPlanes.Instance.ActivePlanes) { SurfacePlane plane = obj.GetComponent <SurfacePlane>(); plane.tag = tag; } }
/// <summary> /// Sets the renderer material. /// </summary> public static void SetPlaneMaterial(this SurfacePlane surfacePlane, Material mat) { Renderer renderer = surfacePlane.gameObject.GetComponent <Renderer>(); if (renderer != null) { renderer.sharedMaterial = mat; } }
private void setChildPositionAtPoint(Vector3 childFloorPosition, SurfacePlane surfacePlane) { Vector3 childHeightOffset = Vector3.up * ScenesData.childHeightOffset; Vector3 planeThickness = (surfacePlane.PlaneThickness * surfacePlane.SurfaceNormal); ChildLocation = childFloorPosition + planeThickness + childHeightOffset; ChildLocationSet = true; ScenesData.child.GetComponent <AreaManager>().ResetPosition(); }
/// <summary> /// Updates the plane geometry to match the bounded plane found by SurfaceMeshesToPlanes. /// </summary> private static void SetPlaneGeometry(this SurfacePlane surfacePlane) { //surfacePlane.SurfaceNormal = surfacePlane.plane.normal; // //// Set the SurfacePlane object to have the same extents as the BoundingPlane object. //surfacePlane.gameObject.transform.position = surfacePlane.Bounds.Center; //surfacePlane.gameObject.transform.rotation = surfacePlane.Bounds.Rotation; //Vector3 extents = surfacePlane.Bounds.Extents * 2; //surfacePlane.gameObject.transform.localScale = extents; }
private void CreateBulletHole(Vector3 position, Vector3 normal, SurfacePlane plane) { GameObject bulletHole = Instantiate(m_bulletHolePrefab, position, Quaternion.LookRotation(normal)) as GameObject; bulletHole.AddComponent <WorldAnchor>(); // does this do anything? bulletHole.transform.parent = this.transform; OrientedBoundingBox obb = OBBMeshIntersection.CreateWorldSpaceOBB(bulletHole.GetComponent <BoxCollider>()); SurfacePlaneDeformationManager.Instance.Embed(bulletHole, obb, plane); }
/// <summary> /// Checks the list of passed in planes for one that might match the passed in bounding plane. /// </summary> /// <param name="planes"></param> /// <param name="plane"></param> /// <returns></returns> private SurfacePlane CheckForExistingPlane(List <SurfacePlane> planes, BoundedPlane plane) { SurfacePlane bestMatch = null; float bestAreaDiff = float.MaxValue; float bestDistance = float.MaxValue; float bestDistPercent = float.MaxValue; PlaneTypes type = GetPossibleType(plane, m_UpNormalThreshold); foreach (SurfacePlane possiblePlane in planes) { if ((possiblePlane.PlaneType & type) == 0) { //Skip this one. continue; } //What is the area difference? float areaDiff = Mathf.Abs(possiblePlane.Plane.Area - plane.Area); float areaDiffPercent = areaDiff / ((possiblePlane.Plane.Area + plane.Area) / 2); //What is the distance difference? float distDiff = (possiblePlane.Plane.Bounds.Center - plane.Bounds.Center).sqrMagnitude; float distChangePercent = distDiff / (possiblePlane.Plane.Bounds.Center.sqrMagnitude + plane.Bounds.Center.sqrMagnitude) / 2; if (areaDiffPercent >= m_MaxAreaDiffPercent || distDiff > m_MaxDistChange) { //The difference in these planes are to different so we can ignore this one. continue; } else if (areaDiffPercent < bestAreaDiff && distDiff < bestDistance) { bestMatch = possiblePlane; bestAreaDiff = areaDiffPercent; bestDistPercent = distChangePercent; distDiff = bestDistance; } else if (areaDiffPercent < bestAreaDiff && areaDiffPercent <= bestDistPercent) { bestMatch = possiblePlane; bestAreaDiff = areaDiffPercent; bestDistPercent = distChangePercent; distDiff = bestDistance; } else if (distDiff < bestDistance && distChangePercent <= areaDiffPercent) { bestMatch = possiblePlane; bestAreaDiff = areaDiffPercent; bestDistPercent = distChangePercent; distDiff = bestDistance; } } return(bestMatch); }
public SurfacePlaneEmbedRequest( SurfacePlane pPlane, Dictionary <Tuple <SurfacePlane, MeshFilter>, float> marginByPlaneAndSpatialMesh, GameObject pMarginVolume, Vector3 pCenterPointOnFrontPlane, Vector3 pCenterPointOnBackPlane, GameObject pEmbedded) : base(pMarginVolume, pCenterPointOnFrontPlane, pCenterPointOnBackPlane, pEmbedded) { plane = pPlane; m_marginByPlaneAndSpatialMesh = marginByPlaneAndSpatialMesh; }
public void GenerateGameBoard(Vector3 requiredSize, float clearance, SurfacePlane plane) { OrientedBoundingBox bb = plane.Plane.Bounds; Quaternion orientation = (plane.transform.forward.y < 0) ? (plane.transform.rotation * Quaternion.FromToRotation(-Vector3.forward, Vector3.forward)) : plane.transform.rotation; // Note that xy in local plane coordinate system correspond to what would be xz in global space Vector3 halfExtents = new Vector3(requiredSize.x, requiredSize.z, requiredSize.y) * 0.5f; int xpos = 0; for (float y = -bb.Extents.y + halfExtents.y; y <= bb.Extents.y - halfExtents.y; y += 2 * halfExtents.y) { int ypos = 0; for (float x = -bb.Extents.x + halfExtents.x; x <= bb.Extents.x - halfExtents.x; x += 2 * halfExtents.x) { Vector3 center = plane.transform.position + orientation * new Vector3(x, y, halfExtents.z + clearance); Collider[] colliders = Physics.OverlapBox(center, halfExtents, orientation); if (colliders.Length == 0) { int cellsFromCamera = 2; GameObject cell; if ((Math.Abs(Camera.main.transform.position.x - center.x) <= (2 * halfExtents.x) * cellsFromCamera) || (Math.Abs(Camera.main.transform.position.z - center.z) <= (2 * halfExtents.z) * cellsFromCamera)) { Debug.Log("Within camera range, placing GamePiece"); cell = Instantiate(GamePiece, gameObject.transform, true); } else { //replace with fisher yates int isMine = getrandom.Next(1, 3); if (isMine == 1) { Debug.Log("Placing mine"); cell = Instantiate(Mine, gameObject.transform, true); } else { Debug.Log("Placing GamePiece"); cell = Instantiate(GamePiece, gameObject.transform, true); } } //cell.transform.localScale = 2 * halfExtents; cell.transform.position = center; // might be more effecient to use a dictionary to locate cells than the gameObject.find cell.transform.name = "cell:" + xpos.ToString() + "," + ypos.ToString(); cell.transform.transform.rotation = orientation; cell.SetActive(true); } ypos++; } xpos++; } }
private bool HasSufficientMargin(SurfacePlane plane, MeshFilter meshFilter, float requiredMargin) { Tuple <SurfacePlane, MeshFilter> key = new Tuple <SurfacePlane, MeshFilter>(plane, meshFilter); //Debug.Log("hash key " + plane.GetInstanceID() + "," + meshFilter.GetInstanceID() + " = " + key.GetHashCode()); float currentMargin; if (m_marginByPlaneAndSpatialMesh.TryGetValue(key, out currentMargin)) { return(currentMargin >= requiredMargin); } return(false); }
public SurfacePlaneEmbedRequest( SurfacePlane pPlane, Dictionary <Tuple <SurfacePlane, MeshFilter>, float> marginByPlaneAndSpatialMesh, OrientedBoundingBox pObb, Vector3 pCenterPointOnFrontPlane, Vector3 pCenterPointOnBackPlane, GameObject pEmbedded, System.Action pOnComplete, bool pTempHighPriorityRender) : base(pObb, pCenterPointOnFrontPlane, pCenterPointOnBackPlane, pEmbedded, pOnComplete, pTempHighPriorityRender) { plane = pPlane; m_marginByPlaneAndSpatialMesh = marginByPlaneAndSpatialMesh; }
/// <summary> /// Generates a collection of Placeable objects in the world and sets them on planes that match their affinity. /// </summary> /// <param name="horizontalSurfaces">Horizontal surface planes (floors, tables).</param> /// <param name="verticalSurfaces">Vertical surface planes (walls).</param> public void PlaceBoxerInWorld(List <GameObject> horizontalSurfaces, List <GameObject> verticalSurfaces) { // Sort the planes by distance to user. horizontalSurfaces.Sort((lhs, rhs) => { Vector3 headPosition = Camera.main.transform.position; Collider rightCollider = rhs.GetComponent <Collider>(); Collider leftCollider = lhs.GetComponent <Collider>(); // This plane is big enough, now we will evaluate how far the plane is from the user's head. // Since planes can be quite large, we should find the closest point on the plane's bounds to the // user's head, rather than just taking the plane's center position. Vector3 rightSpot = rightCollider.ClosestPointOnBounds(headPosition); Vector3 leftSpot = leftCollider.ClosestPointOnBounds(headPosition); return(Vector3.Distance(leftSpot, headPosition).CompareTo(Vector3.Distance(rightSpot, headPosition))); }); //Find the nearest plane to place the boxer on Collider collider = boxerPrefab.GetComponent <Collider>(); int index = FindNearestPlane(horizontalSurfaces, collider.bounds.size); // If we can't find a good plane we will put the object floating in space. Vector3 position = Camera.main.transform.position + Camera.main.transform.forward * 2.0f; Quaternion rotation = Quaternion.identity; // If we do find a good plane we can do something smarter. if (index >= 0) { GameObject surface = horizontalSurfaces[index]; SurfacePlane plane = surface.GetComponent <SurfacePlane>(); Vector3 spawnXZ = Camera.main.transform.position + Camera.main.transform.forward * spawnDist; position = new Vector3(spawnXZ.x, surface.transform.position.y + plane.PlaneThickness, spawnXZ.z); //position = surface.transform.position + (plane.PlaneThickness * plane.SurfaceNormal); position = AdjustPositionWithSpatialMap(position, plane.SurfaceNormal); //rotation = Camera.main.transform.localRotation; // Horizontal objects should face the user. rotation = Quaternion.LookRotation(-Camera.main.transform.forward); rotation.x = 0f; rotation.z = 0f; } //Vector3 finalPosition = AdjustPositionWithSpatialMap(position, surfaceType); GameObject boxer = Instantiate(boxerPrefab, position, rotation) as GameObject; boxer.transform.parent = gameObject.transform; }
/// <summary> /// Initializes a cube game object which represents a surface plane in the scene. /// </summary> /// <param name="p">Plane data from the surface plane which contains the relevant coordinates.</param> /// <param name="display">Specify if the surface plane objects should be displayed in the scene.</param> public void Init(SurfacePlane p, bool display) { Plane = p; gameObject.layer = 30; SetFigureGeometry(); if (display) { SetFigureMaterialByType(); } else { gameObject.GetComponent <Renderer>().material = transparentMaterial; } }
private GameObject findFloorPlane(List <GameObject> horizontalPlanes) { foreach (GameObject horizontalPlane in horizontalPlanes) { SurfacePlane surfacePlane = horizontalPlane.GetComponent <SurfacePlane>(); if (surfacePlane == null) { continue; } if (surfacePlane.PlaneType == PlaneTypes.Floor) { return(horizontalPlane); } } return(null); }
/// <summary> /// Calculate the width and length by max distance of parallel walls. /// </summary> private void SetWallValues() { // Divide walls in parallel and orthogonal walls List <SurfacePlane> parallelWalls = new List <SurfacePlane>(); List <SurfacePlane> orthogonalWalls = new List <SurfacePlane>(); foreach (SurfacePlane wall in walls) { SurfacePlane w = wall; // If the cross product to the frist wall is 0 then walls are parallel otherwise they are orthogonal if (Vector3.Cross(walls[0].Plane.normal, w.Plane.normal).magnitude < 0.5) { // Make sure that all parallel walls have the same orientation w.Bounds.Rotation = walls[0].Bounds.Rotation; parallelWalls.Add(w); } else { if (orthogonalWalls.Count > 0) { // Make sure that all orthogonal walls have the same orientation w.Bounds.Rotation = orthogonalWalls[0].Bounds.Rotation; } orthogonalWalls.Add(w); } } // Set the distance within parallel and orthogonal walls float parallelDistance = GetMaxWallDistance(parallelWalls); float orthogonalDistance = GetMaxWallDistance(orthogonalWalls); // Set the larger of the distance as the wall length and the other as the wall width if (parallelDistance > orthogonalDistance) { widths[2] = orthogonalDistance; lengths[2] = parallelDistance; } else { widths[2] = parallelDistance; lengths[2] = orthogonalDistance; } }
/// <summary> /// Returns the volume of the room by calculating height * width * length. /// </summary> /// <param name="floor">Surface plane which represents the floor.</param> /// <param name="ceiling">Surface plane which represents the ceiling.</param> /// <param name="walls">Surface planes which represents the walls.</param> public void CalculateRoomVolume(SurfacePlane floor, SurfacePlane ceiling, List <SurfacePlane> walls) { this.floor = floor; this.ceiling = ceiling; this.walls = walls; // Case 1: floor, ceiling and wall(s) exist if (floor.Area > 0 && ceiling.Area > 0 && walls.Count >= 1) { CalculateByFloorCeilingWalls(); } // Case 2: floor and ceiling exist else if (floor.Area > 0 && ceiling.Area > 0 && walls.Count == 0) { CalculateByFloorCeiling(); } // Case 3: floor and wall(s) exist else if (floor.Area > 0 && ceiling.Area == 0 && walls.Count > 0) { CalculateByFloorWalls(); } // Case 4: ceiling and wall(s) exist else if (floor.Area == 0 && ceiling.Area > 0 && walls.Count > 0) { CalculateByCeilingWalls(); } // Case 5: walls exist else if (floor.Area == 0 && ceiling.Area == 0 && walls.Count > 1) { CalculateByWalls(); } else // Cannot calculate volume { Debug.Log("Cannot calculate volume"); return; } // Calculate the average of the width and length from the floor, ceiling and walls RoomWidth = widths.Where(w => w > 0).Average(); RoomLength = lengths.Where(l => l > 0).Average(); RoomVolume = RoomHeight * RoomWidth * RoomLength; Debug.Log("Volume: " + RoomVolume); }
public List <GameObject> GetTables() { PlaneTypes desired_types = PlaneTypes.Table; List <GameObject> planes = new List <GameObject>(); foreach (GameObject plane in SurfaceMeshesToPlanes.Instance.ActivePlanes) { SurfacePlane surfacePlane = plane.GetComponent <SurfacePlane>(); // Only tables below eye level. SurfacePlane has the unfortunate problem // that it creates tables with planes oriented downwards. We ignore these // (but maybe we should rotate?). if ((surfacePlane.PlaneType & desired_types) == surfacePlane.PlaneType) { Debug.Log("Found: " + surfacePlane.transform.position.ToString() + ", " + surfacePlane.Plane.Plane.normal.ToString("F2")); } if ((surfacePlane.PlaneType & desired_types) == surfacePlane.PlaneType && surfacePlane.transform.position.y < 0 && surfacePlane.Plane.Plane.normal.y > 0) { planes.Add(plane); } } return(planes); }
void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "Plane") { plane = other.gameObject; surfaceplane = plane.GetComponent <SurfacePlane>(); if (surfaceplane.PlaneType == PlaneTypes.Wall) { NearWallFrag = 1; return; } else if (surfaceplane.PlaneType == PlaneTypes.Ceiling) { CellingFrag = 1; Failed = 1; } else { NearWallFrag = 0; return; } } }