Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <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))));
        }
    }
Exemple #4
0
    // 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);
        }
    }
Exemple #7
0
    // 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);
                }
            }
        }
    }
Exemple #8
0
    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);
 }
Exemple #12
0
    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);
    }
Exemple #13
0
 private void SetPlanesVisible(bool visible)
 {
     foreach (GameObject obj in SurfaceMeshesToPlanes.Instance.ActivePlanes)
     {
         SurfacePlane plane = obj.GetComponent <SurfacePlane>();
         plane.IsVisible = visible;
     }
 }
Exemple #14
0
 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);
    }
Exemple #19
0
        /// <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);
        }
Exemple #20
0
 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;
 }
Exemple #21
0
    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++;
        }
    }
Exemple #22
0
    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;
    }
Exemple #25
0
    /// <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);
    }
Exemple #29
0
    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);
    }
Exemple #30
0
 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;
         }
     }
 }