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); }
} //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()
//============================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); // } }