Ejemplo n.º 1
0
    int findNearestCornerID(Vector3 Pi)
    {
        int wallID_Pi = InRoomRetrieval.FindWall(new Vector2(Pi.x, Pi.z));

        //find nearest corner
        float[] distances2D = new float[Room.floorCorners.Length];
        for (int j = 0; j < Room.floorCorners.Length; j++)
        {
            distances2D[j] = (new Vector2(Pi.x, Pi.z) -
                              new Vector2(Room.floorCorners[j].x,
                                          Room.floorCorners[j].z)).magnitude;
        }
        int cornerID_Pi = InRoomRetrieval.findSmallestIDAt(distances2D);

        return(cornerID_Pi);
    }
Ejemplo n.º 2
0
    }    //getDistanceScore()

    void getSingleScore(int i)
    {
        /**
         * Door, windows and fireplace term:
         * Vector3[][]Doors windows Fireplaces: (namecode,wallID,0)(center)(extents) Vector3(width,depth,height)
         * Vector3[,] walls: (start point)(end point)(normal to inside the room)
         */
        /**
         * Nearest wall and corner term
         */
        Vector3 Pi = boxesT1[i].transform.position;
        Vector3 Ei = boxesT1[i].collider.bounds.extents;

        Vector2 A        = new Vector2(Pi.x, Pi.z);
        int     wallID   = InRoomRetrieval.FindWall(A);
        int     cornerID = findNearestCornerID(new Vector3(A.x, 0, A.y));

        float walldistance = InRoomRetrieval.DistanceToRay2D(
            A,
            new Vector2(Room.walls[wallID, 0].x, Room.walls[wallID, 0].z),
            new Vector2(Room.walls[wallID, 1].x, Room.walls[wallID, 1].z))
                             - Ei.z;

        walldistance = Mathf.Max(walldistance, 0);
        float cornerdistance = (new Vector2(Room.floorCorners[cornerID].x,
                                            Room.floorCorners[cornerID].z)
                                - A).magnitude - new Vector2(Ei.x, Ei.z).magnitude;

        cornerdistance = Mathf.Max(cornerdistance, 0);

        double NearestWallDistanceScore   = 100 / (walldistance + 1) / (10 * i + 1) * Ei.y;
        double NearestCornerDistanceScore = 100 / (cornerdistance + 1) / (10 * i + 1) * Ei.y;

        /**
         * Rotation check
         */
        float rotationY  = boxesT1[i].transform.localEulerAngles.y;
        float targetedRY = Vector3.Angle(new Vector3(0, 0, 1), Room.walls[wallID, 2]);

        if (Mathf.Abs(rotationY - targetedRY) > 45)
        {
            NearestWallDistanceScore = NearestWallDistanceScore / 2;
        }


        /**
         * Window shielded score
         */
        double WindowShieldedScore = 0;

        for (int j = 0; j < Windows.GetLength(0); j++)
        {
            float cosTheta       = 0;
            float windowDistance = 0;
            int   windowWall     = (int)Windows[j][0].y;
            //if the box nearest wall is the window wall
            if (wallID == windowWall)
            {
                //the box should not be higher than the window:
                //windowcenter.y-boxcenter.y
                float heightDelta = Windows[j][1].y - Pi.y;
                //>0 and even > sum of two extents in Y
                //alow furniture that a litter higher than window lowest bounds
                if (heightDelta < Windows[j][2].y * 0.3f + Ei.y)
                {
                    //cos(theta)
                    Vector3 pointingtoPi = Pi - Windows[j][1];                //pointing to Pi
                    pointingtoPi.y = 0;
                    //----2D distance
                    windowDistance  = pointingtoPi.magnitude;
                    windowDistance -= Mathf.Max(boxesT1[i].collider.bounds.extents.x,
                                                boxesT1[i].collider.bounds.extents.z);
                    windowDistance = Mathf.Max(windowDistance, 0);

                    pointingtoPi = pointingtoPi.normalized;                  //and normalise it
                    //the normalized wall normal * pointingtoPi
                    cosTheta = Vector3.Dot(Room.walls[windowWall, 2], pointingtoPi);
                }                //if box is lower than the window, it doesn't matter
                else
                {
                    WindowShieldedScore = 100;
                }
            }            //if the box is not near to the window, it's doesn't matter too
            else
            {
                WindowShieldedScore = 100;
            }

            WindowShieldedScore += windowDistance / (10 * cosTheta + 1);

            if (cosTheta > 0.8)          //0.71 if cos(theta)>1/sqrt(2)
            {
                WindowShieldedScore = WindowShieldedScore + (windowDistance + 1) / (cosTheta + 1)
                                      - 10 / (windowDistance + 1);
            }
        }

        /**
         * Fireplace shielded score
         */
        double FireplaceShieldedScore = 0;

        for (int j = 0; j < Fireplaces.GetLength(0); j++)
        {
            float cosTheta          = 0; //when theta= 90 degree, very important
            float FireplaceDistance = 0;
            int   fireplaceWall     = (int)Fireplaces[j][0].y;
            //if the box nearest wall is the fireplace wall
            if (wallID == fireplaceWall)
            {
                //cos(theta)
                Vector3 pointingtoPi = Pi - Fireplaces[j][1];            //pointing to Pi
                pointingtoPi.y = 0;
                //----2D distance
                FireplaceDistance  = pointingtoPi.magnitude;
                FireplaceDistance -= Mathf.Max(boxesT1[i].collider.bounds.extents.x,
                                               boxesT1[i].collider.bounds.extents.z);
                FireplaceDistance = Mathf.Max(FireplaceDistance, 0);
                //if center 2d distance larger than fireplace depth*1.5
                if (FireplaceDistance <= Fireplaces[j][3].y * 1.5f)
                {
                    pointingtoPi = pointingtoPi.normalized;                  //and normalise it
                    //the normalized wall normal * pointingtoPi
                    cosTheta = Vector3.Dot(Room.walls[fireplaceWall, 2], pointingtoPi);
                }                //else ignore
                else
                {
                    FireplaceShieldedScore = 100;
                }
            }            //else ignore
            else
            {
                FireplaceShieldedScore = 100;
            }

            FireplaceShieldedScore += (FireplaceDistance + 1) / (cosTheta + 1);
            if (cosTheta > 0.87)          //expected narrow than window
            {
                FireplaceShieldedScore = FireplaceShieldedScore - FireplaceDistance / (cosTheta + 1)
                                         - 10 / (FireplaceDistance + 1);
            }
        }

        /**
         * Door path score
         */
//		Debug.Log(boxesT1[i].name+" corner score was "+NearestCornerDistanceScore);
        double DoorPathScore = 0;

        for (int j = 0; j < Doors.GetLength(0); j++)
        {
            float cosTheta     = 0;
            float DoorDistance = 0;
            int   doorCorner   = findNearestCornerID(Doors[j][1]);
            if (cornerID == doorCorner)
            {
                NearestCornerDistanceScore = 0;
//				Debug.Log(boxesT1[i].name+" near door");
                int doorWall = (int)Doors[j][0].y;
                //cos(theta)
                Vector3 pointingtoPi = Pi - Doors[j][1];            //pointing to Pi
                pointingtoPi.y = 0;
                //----2D distance
                float doorDistance = pointingtoPi.magnitude;
                doorDistance -= Mathf.Max(boxesT1[i].collider.bounds.extents.x,
                                          boxesT1[i].collider.bounds.extents.z);
                doorDistance = Mathf.Max(doorDistance, 0);
                pointingtoPi = pointingtoPi.normalized;              //then normalise it
                //the normalized wall normal * pointingtoPi
                cosTheta = Vector3.Dot(Room.walls[doorWall, 2], pointingtoPi);
            }            //else it should move far away from doors
            else
            {
                DoorPathScore = 100;
            }
            float theta = Mathf.Acos(cosTheta) * 180 / Mathf.PI;
            DoorPathScore += DoorDistance * theta;

//			DoorPathScore+=(DoorDistance+1)/(cosTheta+1);
            if (cosTheta > 0.71)                //expected wider than window
            {
                DoorPathScore = DoorPathScore - //DoorDistance/(cosTheta+1)
                                -100 / (DoorDistance + 1);
            }
        }
//		Debug.Log(boxesT1[i].name+" DoorPathScore become "+DoorPathScore);


//		Debug.Log("NearestWallDistanceScore "+NearestWallDistanceScore);
//		Debug.Log("NearestCornerDistanceScore"+NearestCornerDistanceScore);
//		Debug.Log("DoorPathScore "+DoorPathScore);
//		Debug.Log("WindowShieldedScore "+WindowShieldedScore);
//		Debug.Log("FireplaceShieldedScore "+FireplaceShieldedScore);

        currentSingleScores[i] =
            20 * NearestWallDistanceScore + NearestCornerDistanceScore
            + DoorPathScore + WindowShieldedScore + FireplaceShieldedScore;
    }    //getSingleScore()
Ejemplo n.º 3
0
    //============================rotate()========================
    void rotate(GameObject furniture)
    {
        Vector3 Pi     = furniture.collider.bounds.center;
        Vector3 Ei     = furniture.collider.bounds.extents;
        int     wallID = InRoomRetrieval.FindWall(new Vector2(Pi.x, Pi.z));

        float walldistance = InRoomRetrieval.DistanceToRay2D(
            new Vector2(Pi.x, Pi.z),
            new Vector2(Room.walls[wallID, 0].x, Room.walls[wallID, 0].z),
            new Vector2(Room.walls[wallID, 1].x, Room.walls[wallID, 1].z));

        Vector3 from      = new Vector3(0, 0, 1);
        Vector3 to        = Room.walls[wallID, 2];
        float   rotationY = Vector3.Angle(from, to);

//		rotationY=rotationY-floorplanRotation.y;

        if (Pi.x < Room.roomCenter.x && Pi.z < Room.roomCenter.z)
        {
            //in III phase
            if (rotationY < 40)
            {
                rotationY = 0;
            }
            if (rotationY > 50)
            {
                rotationY = 90;
            }
        }
        else if (Pi.x < Room.roomCenter.x && Pi.z > Room.roomCenter.z)
        {
            //in II phase
            if (rotationY > 50 && rotationY < 130)
            {
                rotationY = 90;
            }
            if (rotationY < 40 || rotationY > 140)
            {
                rotationY = 180;
            }
        }
        else if (Pi.x > Room.roomCenter.x && Pi.z > Room.roomCenter.z)
        {
            //in I phase
            if (rotationY < 40 || rotationY > 140)
            {
                rotationY = 180;
            }
            if (rotationY > 50 && rotationY < 130)
            {
                rotationY = 270;
            }
//			Debug.Log("//in I phase, rotationY="+rotationY);
        }
        else
        {
            //in IV phase
            if (rotationY < 40)
            {
                rotationY = 0;
            }
            if (rotationY > 50)
            {
                rotationY = 270;
            }
//			Debug.Log("//in IV phase, rotationY="+rotationY);
        }

        if (Ei.z < Ei.x || walldistance > Ei.z)
        {
            furniture.transform.localEulerAngles = new Vector3(0, rotationY, 0);
//			Debug.LogError(furniture.name+" rotates: "+rotationY);
        }
//		else{
//			Debug.LogError(furniture.name+"--------------------------------");
//			Debug.LogError(Pi+" room center"+Room.roomCenter);
//			Debug.LogError(Ei.x+"  x> z?  "+Ei.z);
//			Debug.LogError(walldistance);
//		}
    }