Looks like a building to me |
1 - Roofs redone
Since I initially used Python to create the roof meshes I had to go back and redo the setup, but that turned out to be not that complicated. Instead of using a curve and having to pass the point positions into the coordinate parameter, I used VEX to create a polygon and add the points to it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
float temp[] = detail('op:../../Instance/', 'gfloor_curve_points', 0); | |
int numPt = len(temp)/3; | |
int prim = addprim(geoself(), 'poly'); | |
for (int i = 0; i < numPt; i++){ | |
int startIndex = i * 3; | |
vector pos = set(temp[startIndex], temp[startIndex + 1], temp[startIndex + 2]); | |
int pt = addpoint(geoself(), pos); | |
int vert = addvertex(geoself(), prim, pt); | |
} |
EDIT: I added an attribute wrangle node to add a material attribute.
2 - Ground Floor Complete
Since the ground Floor was done in a similar way to the mid floors I won't go into much detail about the process. I cleaned up the code for placing the wall tiles slightly and added a new section for adding unique tiles. I limited the number of unique tiles to 1 per building side, just to simplify things, but in theory it would be possible. I even tried it, but it got a bit buggy.
Here is the code for the unique tiles, nothing special.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//VARIABLES | |
int addFSep = chi('../../chk_gfloor_sep'); | |
//Points | |
int points[] = primpoints(geoself(), 0); | |
int numPt = @numpt; | |
int cornerPoints[] = points; | |
int wallPoints[]; | |
int wallPointIndex[]; | |
int basePoints[] = points; | |
int sepPoints[] = basePoints; | |
for(int i = 0; i < len(points); i++) { | |
sepPoints[i] += len(points); | |
} | |
append(points, points[0]); | |
int sortedIndices[] = points; | |
int numCorners = len(cornerPoints); | |
int usedBSides[]; | |
//unique pieces | |
string uniquePieces = chs('../kit_storage/gfloor_kit_unique'); | |
string uniquePieceArray[] = split(uniquePieces); | |
int numUnique = chi('../../mp_unique_pieces'); | |
float wallHeight = getbbox_size(chs('../../' + uniquePieceArray[0] + '/' + uniquePieceArray[0] + '/file'))[1];; | |
//separation pieces | |
string fSep = chs('../kit_storage/fsep_kit_wall'); | |
string sepArray[] = split(fSep); | |
float sepWidth = getbbox_size(chs('../../' + sepArray[0] + '/' + sepArray[0] + '/file'))[0]; | |
//piece x size | |
float xWidth[]; | |
vector norm[]; | |
vector pPos[]; | |
//add points | |
for (int i = 0; i < numUnique; i++){ | |
//Piece Info | |
int index = chi('../../gfloor_unique_piece_index' + itoa(i+1)) % len(uniquePieceArray); | |
int side = chi('../../gfloor_unique_building_side' + itoa(i+1)); | |
float offset = chf('../../gfloor_unique_offset' + itoa(i+1)); | |
string pieceName = uniquePieceArray[index]; | |
float pieceWidth = getbbox_size(chs('../../' + pieceName + '/' + pieceName + '/file'))[0]; | |
int startIndex = side; | |
if(find(usedBSides, side) < 0) { | |
//Edge Info | |
int startPoint = sortedIndices[startIndex]; | |
int endPoint = sortedIndices[startIndex + 1]; | |
vector startPos = pointattrib(geoself(), 'P', startPoint, 1); | |
vector endPos = pointattrib(geoself(), 'P', endPoint, 1); | |
vector vec = endPos - startPos; | |
float dist = length(vec) - ( pointattrib(geoself(), 'piece_x_size', startPoint, 1) + pointattrib(geoself(), 'piece_x_size', endPoint, 1)); | |
vector normal = normalize(set(vec[2], vec[1], vec[0] * -1)); | |
if (dist > pieceWidth) { | |
startPos += normalize(vec) * (pointattrib(geoself(), 'piece_x_size', startPoint, 1) + pieceWidth/2); | |
dist -= pieceWidth; | |
vector pos = startPos + offset * dist * normalize(vec); | |
int pt = addpoint(geoself(), pos); | |
setpointattrib(geoself(), 'piece_x_size', pt, pieceWidth/2,'set'); | |
setpointattrib(geoself(), 'scale', pt, set(1,1,1),'set'); | |
setpointattrib(geoself(), 'N', pt, normal,'set'); | |
setpointattrib(geoself(), 'instance', pt, '../../'+pieceName,'set'); | |
setpointattrib(geoself(), "row_type", pt, 'wall', "set"); | |
insert(basePoints, startIndex + 1, pt); | |
append(usedBSides, side); | |
append(wallPoints, pt); | |
append(xWidth, pieceWidth); | |
append(pPos, pos); | |
append(norm, normal); | |
append(wallPointIndex, startIndex + 1); | |
} | |
} | |
else{ | |
printf('Side already used. \n'); | |
} | |
} | |
//add separation | |
if(addFSep == 1){ | |
for (int i = 0; i < len(wallPoints); i++) { | |
float x = xWidth[i]; | |
float scaleX = x / sepWidth; | |
int index = wallPointIndex[i]; | |
int pt = addpoint(geoself(), pPos[i] + set(0, wallHeight, 0)); | |
setpointattrib(geoself(), 'piece_x_size', pt, xWidth[i],'set'); | |
setpointattrib(geoself(), 'scale', pt, set(scaleX,1,1),'set'); | |
setpointattrib(geoself(), 'N', pt, norm[i],'set'); | |
setpointattrib(geoself(), 'instance', pt, '../../'+sepArray[0],'set'); | |
setpointattrib(geoself(), "row_type", pt, 'sep', "set"); | |
insert(sepPoints, index, pt); | |
} | |
} | |
setdetailattrib(geoself(), 'base_Points', basePoints, 'set'); | |
setdetailattrib(geoself(), 'sep_Points', sepPoints, 'set'); |
This could and should probably be optimised.
Just for completeness sake I'll add the code for placing the wall tiles, but it is not any different from the middle floor section.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//VARIABLES | |
int basePoints[] = detail(geoself(), 'base_Points'); | |
append(basePoints, basePoints[0]); | |
int points[] = primpoints(geoself(), 0); | |
int numPt = len(points); | |
int numRows = 2 - (1 - chi('../../chk_gfloor_sep')); | |
//modular kit piece arrays | |
//pillars | |
string pillars = chs('../kit_storage/gfloor_kit_pillar'); | |
string pillarArray[] = split(pillars); | |
int pillarIndex = int(chi('../../gfloor_pillar_index')%len(pillarArray)); | |
string pillarRef = '../../'+ pillarArray[pillarIndex]; | |
int numPillars = chi('../../gfloor_num_pillars'); | |
float pillarWidth = float(getbbox_size(chs('../../' + pillarArray[0] + '/' + pillarArray[0] + '/file' ))[0]); | |
//plain wall | |
string wall = chs('../kit_storage/gfloor_kit_wall'); | |
string wallArray[] = split(wall); | |
int wallIndex = chi('../../gfloor_wall_index') % len(wallArray); | |
float wallWidth = getbbox_size(chs('../../' + wallArray[wallIndex] + '/' + wallArray[wallIndex] +'/file'))[0]; | |
float wallHeight = getbbox_size(chs('../../' + wallArray[wallIndex] + '/' + wallArray[wallIndex] +'/file'))[1]; | |
string wallRef = '../../' + wallArray[wallIndex]; | |
int numWallPieces = chi('../../gfloor_num_pieces_btwn_pillars'); | |
//windows | |
string windows = chs('../kit_storage/gfloor_kit_sw'); | |
string windowArray[] = split(windows); | |
int windowIndex = chi('../../gfloor_wframe_index') % len(windowArray); | |
string pieceRef = '../../' + windowArray[windowIndex]; | |
float pieceWidth = getbbox_size(chs('../../' + windowArray[windowIndex] + '/' + windowArray[windowIndex] +'/file'))[0]; | |
// floor separation | |
string fSep = chs('../kit_storage/fsep_kit_wall'); | |
string fSepPillar = chs('../kit_storage/fsep_kit_pillar'); | |
string fSepRef = '../../' + rstrip(fSep); | |
string fSepPillarRef = '../../' + rstrip(fSepPillar); | |
//PLACE PIECES | |
for (int row = 0; row < numRows; row++){ | |
float offset = row * wallHeight; | |
//loop through corners | |
for (int c = 0; c < len(basePoints) - 1; c++) { | |
int startPoint = basePoints[c]; | |
int endPoint = basePoints[c + 1]; | |
//PREP | |
vector startPointPos = pointattrib(geoself(), 'P', startPoint, 1); | |
vector endPointPos = pointattrib(geoself(), 'P',endPoint, 1); | |
vector dir = normalize(endPointPos - startPointPos); | |
// start and end position, taking corner piece width into consideration | |
vector startPos = startPointPos + (pointattrib(geoself(), 'piece_x_size', startPoint, 1)*dir); | |
vector endPos = endPointPos - (pointattrib(geoself(), 'piece_x_size', endPoint, 1)*dir); | |
//normal for placing the pieces on the edges | |
vector n = set(dir[2], 0, dir[0] * -1); | |
float dist = distance(startPos, endPos); | |
if ( (pointattrib(geoself(), 'piece_x_size', startPoint, 1) + pointattrib(geoself(), 'piece_x_size', endPoint, 1)) < distance(startPointPos, endPointPos) ) { | |
//CALCULATE SECTIONS | |
if (numWallPieces == 0){ | |
numPillars = 1; | |
} | |
float sectionWidth = (numWallPieces * wallWidth) * clamp(numPillars - 1, 0, 10) + numPillars * pillarWidth; | |
sectionWidth *= int(sectionWidth < dist); | |
int numSections = int((sectionWidth != 0)); | |
//num tiles on each side of pillar section | |
float restWidth = dist - sectionWidth; | |
int numPieces; | |
if (sectionWidth != 0) { | |
numPieces = int(floor((restWidth/2)/wallWidth)); | |
numPieces -= (numPieces % 2) * (1 - int(sectionWidth < dist)); | |
} | |
else { | |
numPieces = int(floor(restWidth / wallWidth)); | |
} | |
//filler | |
float fillerWidth; | |
if (sectionWidth != 0) { | |
fillerWidth = (restWidth - ((numPieces * 2) * wallWidth))/2; | |
} | |
else { | |
fillerWidth = (restWidth - ((numPieces) * wallWidth))/2; | |
} | |
float fillerScaleX = fillerWidth / wallWidth; | |
//PLACE PIECES | |
vector tempPos; | |
vector tempStartPos; | |
vector tempEndPos; | |
vector pillarStartPos; | |
int tempPt; | |
//filler | |
if(numSections != 0 || numPieces != 0){ | |
//set ref | |
string fillerRef = ''; | |
if(row == 0){ | |
fillerRef = wallRef; | |
} | |
else if(row == 1){ | |
fillerRef = fSepRef; | |
fillerScaleX *= 2; | |
} | |
if (fillerWidth != 0) { | |
tempPos = startPos + (fillerWidth/2) * dir + set(0, offset, 0); | |
tempStartPos = tempPos; | |
tempPt = addpoint(geoself(), tempStartPos); | |
setpointattrib(geoself(), 'instance', tempPt, fillerRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(fillerScaleX,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
tempPos = endPos - (fillerWidth/2) * dir + set(0, offset, 0); | |
tempEndPos = tempPos; | |
tempPt = addpoint(geoself(), tempEndPos); | |
setpointattrib(geoself(), 'instance', tempPt, fillerRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(fillerScaleX,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
} | |
} | |
else { | |
//set ref | |
string fillerRef = ''; | |
if(row == 0){ | |
fillerRef = wallRef; | |
} | |
else if(row == 1){ | |
fillerRef = fSepRef; | |
fillerScaleX *= 2; | |
} | |
if (fillerWidth != 0) { | |
tempPos = startPos + (fillerWidth * dir) + set(0, offset, 0); | |
tempPt = addpoint(geoself(), tempPos); | |
setpointattrib(geoself(), 'instance', tempPt, fillerRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(fillerScaleX * 2,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
} | |
} | |
// add additional pieces | |
if (numPieces != 0){ | |
string spareRef = ''; | |
float spareScaleX = 1; | |
if (row == 0){ | |
spareRef = pieceRef; | |
} | |
else if (row == 1){ | |
spareRef = fSepRef; | |
spareScaleX *= 2; | |
} | |
vector start, end; | |
if (sectionWidth != 0) { | |
for (int p = 0; p < numPieces; p++){ | |
tempPos = tempStartPos + (pieceWidth * dir)/2 + (fillerWidth * dir)/2 + (pieceWidth * p) * dir; | |
tempPt = addpoint(geoself(), tempPos); | |
start = tempPos; | |
setpointattrib(geoself(), 'instance', tempPt, spareRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(spareScaleX,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
tempPos = tempEndPos - (pieceWidth * dir)/2 - (fillerWidth * dir)/2 - (pieceWidth * p) * dir; | |
tempPt = addpoint(geoself(), tempPos); | |
end = tempPos; | |
setpointattrib(geoself(), 'instance', tempPt, spareRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(spareScaleX,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
} | |
tempStartPos = start; | |
tempEndPos = end; | |
pillarStartPos = tempStartPos + pieceWidth/2 * dir; | |
} | |
else{ | |
for (int p = 0; p < numPieces; p++) { | |
tempPos = tempStartPos + (pieceWidth * dir)/2 + (fillerWidth * dir)/2 + (pieceWidth * p) * dir; | |
tempPt = addpoint(geoself(), tempPos); | |
setpointattrib(geoself(), 'instance', tempPt, spareRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(spareScaleX,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
} | |
} | |
} | |
else{ | |
pillarStartPos = tempStartPos + fillerWidth/2 * dir; | |
} | |
//add pillar sections | |
if(numSections != 0){ | |
string wRef, pRef = ''; | |
float xScale = 1; | |
if (row == 0){ | |
wRef = pieceRef; | |
pRef = pillarRef; | |
xScale = 1; | |
} | |
else if (row == 1){ | |
wRef = fSepRef; | |
pRef = fSepPillarRef; | |
xScale = 1; | |
} | |
for(int pl = 0; pl < numPillars; pl++){ | |
vector pillarPos; | |
xScale = 1; | |
pillarPos = pillarStartPos + (pillarWidth/2 * dir) + (pillarWidth * pl * dir) + (numWallPieces * pieceWidth * dir * pl); | |
tempPt = addpoint(geoself(), pillarPos); | |
setpointattrib(geoself(), 'instance', tempPt, pRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(xScale,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
for (int sWall = 0; sWall < numWallPieces; sWall++) { | |
if(pl < numPillars - 1){ | |
if (row == 1) { | |
xScale = 2; | |
} | |
vector wallPos = pillarPos + (pillarWidth/2 * dir) + (wallWidth/2 * dir) + (wallWidth * sWall * dir); | |
tempPt = addpoint(geoself(), wallPos); | |
setpointattrib(geoself(), 'instance', tempPt, wRef, 'set'); | |
setpointattrib(geoself(), 'scale', tempPt, set(xScale,1,1), 'set'); | |
setpointattrib(geoself(), 'N', tempPt, n, 'set'); | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
This is basically how far I got over the last couple of days. From here on I will focus on sorting the material IDs first and then move on to removing wall sections and creating LODs.
But again: It's a building !!!
Building Variation |
Building Generator in UE4 |
No comments:
Post a Comment