mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
Added material assignment in model view, citybuilder, and transalte scale and offset window to model view.
This commit is contained in:
@@ -14,6 +14,7 @@ This file is part of the IceTech GPL Source Code.
|
||||
|
||||
#include "qe3.h"
|
||||
#include "CityBuilder.h"
|
||||
#include "../../framework/DeclEntityDef.h"
|
||||
|
||||
extern int mapModified;
|
||||
|
||||
@@ -31,22 +32,26 @@ struct cityBounds_t {
|
||||
idVec3 maxs;
|
||||
};
|
||||
|
||||
static const float CITY_DEFAULT_HALF_SIZE = 4096.0f;
|
||||
static const float CITY_MIN_SIZE = 3072.0f;
|
||||
struct cityMesh_t {
|
||||
idStr model;
|
||||
idBounds bounds;
|
||||
idVec3 size;
|
||||
};
|
||||
|
||||
static const float CITY_DEFAULT_HALF_SIZE = 6144.0f;
|
||||
static const float CITY_MIN_SIZE = 4096.0f;
|
||||
static const float CITY_MAX_SIZE = 65536.0f;
|
||||
static const float CITY_ROAD_PITCH = 1152.0f;
|
||||
static const float CITY_ROAD_WIDTH = 256.0f;
|
||||
static const float CITY_SIDEWALK_WIDTH = 80.0f;
|
||||
static const float CITY_CURB_WIDTH = 12.0f;
|
||||
static const float CITY_ROAD_PITCH = 1408.0f;
|
||||
static const float CITY_ROAD_WIDTH = 384.0f;
|
||||
static const float CITY_SIDEWALK_WIDTH = 128.0f;
|
||||
static const float CITY_CURB_WIDTH = 16.0f;
|
||||
static const float CITY_CEILING_HEIGHT = 1536.0f;
|
||||
static const float CITY_TEXTURE_SIZE = 1024.0f;
|
||||
static const float CITY_ROAD_TEXTURE_LENGTH = 512.0f;
|
||||
static const float CITY_SIDEWALK_TEXTURE_LENGTH = 256.0f;
|
||||
static const float CITY_BUILDING_TEXTURE_WIDTH = 256.0f;
|
||||
static const float CITY_BUILDING_TEXTURE_HEIGHT = 384.0f;
|
||||
static const float CITY_BUILDING_EDGE_SETBACK = 96.0f;
|
||||
static const float CITY_BUILDING_LOT_SIZE = 640.0f;
|
||||
static const float CITY_BUILDING_ALLEY = 56.0f;
|
||||
static const float CITY_BUILDING_EDGE_SETBACK = 0.0f;
|
||||
static const float CITY_BUILDING_ALLEY = 0.0f;
|
||||
static const float CITY_MODEL_LOT_EXTRA = 64.0f;
|
||||
static const float CITY_POINT_LIGHT_RADIUS = 300000.0f;
|
||||
|
||||
static const char* CITY_MAT_MARS_DIRT = "textures/mars_citybuilder/mars_dirt";
|
||||
@@ -54,8 +59,8 @@ static const char* CITY_MAT_MARS_ROAD = "textures/mars_citybuilder/mars_road_dus
|
||||
static const char* CITY_MAT_MARS_ROAD_EAST_WEST = "textures/mars_citybuilder/mars_road_dusty_center_east_west";
|
||||
static const char* CITY_MAT_MARS_ROAD_INTERSECTION = "textures/mars_citybuilder/mars_road_dusty_intersection";
|
||||
static const char* CITY_MAT_MARS_SIDEWALK = "textures/mars_citybuilder/mars_sidewalk_dusty";
|
||||
static const char* CITY_MAT_MARS_BUILDING_01 = "textures/mars_citybuilder/mars_building_dark_01";
|
||||
static const char* CITY_MAT_MARS_BUILDING_02 = "textures/mars_citybuilder/mars_building_dark_02";
|
||||
static const char* CITY_MESH_DEF = "citybuilder_meshes";
|
||||
static const char* CITY_FALLBACK_MESH = "models/offices/office.md5static";
|
||||
static const idVec3 CITY_POINT_LIGHT_ORIGIN(-3200.0f, 3336.0f, 0.0f);
|
||||
static const idVec3 CITY_POINT_LIGHT_COLOR(242.0f / 255.0f, 160.0f / 255.0f, 130.0f / 255.0f);
|
||||
|
||||
@@ -107,6 +112,30 @@ static float City_TexShift(float worldCoord, float scale) {
|
||||
return shift;
|
||||
}
|
||||
|
||||
static float City_TexShiftFloorXCenter(float worldCenter, float scale) {
|
||||
if (scale == 0.0f) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float shift = fmod(CITY_TEXTURE_SIZE * 0.5f - worldCenter / scale, CITY_TEXTURE_SIZE);
|
||||
if (shift < 0.0f) {
|
||||
shift += CITY_TEXTURE_SIZE;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
static float City_TexShiftFloorYCenter(float worldCenter, float scale) {
|
||||
if (scale == 0.0f) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float shift = fmod(CITY_TEXTURE_SIZE * 0.5f + worldCenter / scale, CITY_TEXTURE_SIZE);
|
||||
if (shift < 0.0f) {
|
||||
shift += CITY_TEXTURE_SIZE;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
static void City_SetTexdef(texdef_t& td, const char* material, float scale0 = 0.5f, float scale1 = 0.5f, float rotate = 0.0f, float shift0 = 0.0f, float shift1 = 0.0f) {
|
||||
td.SetName(material);
|
||||
td.shift[0] = shift0;
|
||||
@@ -147,7 +176,7 @@ static idEditorBrush* City_AddVerticalRoadBrush(float x, float y0, float y1, con
|
||||
const float scale1 = City_TexScale(CITY_ROAD_TEXTURE_LENGTH);
|
||||
const idVec3 mins(x - roadHalf, y0, bounds.mins.z);
|
||||
const idVec3 maxs(x + roadHalf, y1, bounds.mins.z + 8.0f);
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_ROAD_EAST_WEST, scale0, scale1, 0.0f, City_TexShift(mins.x, scale0), City_TexShift(mins.y, scale1), stats);
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_ROAD_EAST_WEST, scale0, scale1, 0.0f, City_TexShiftFloorXCenter(x, scale0), City_TexShift(maxs.y, scale1), stats);
|
||||
}
|
||||
|
||||
static idEditorBrush* City_AddHorizontalRoadBrush(float x0, float x1, float y, const cityBounds_t& bounds, cityStats_t& stats) {
|
||||
@@ -156,7 +185,7 @@ static idEditorBrush* City_AddHorizontalRoadBrush(float x0, float x1, float y, c
|
||||
const float scale1 = City_TexScale(CITY_ROAD_WIDTH);
|
||||
const idVec3 mins(x0, y - roadHalf, bounds.mins.z);
|
||||
const idVec3 maxs(x1, y + roadHalf, bounds.mins.z + 8.0f);
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_ROAD, scale0, scale1, 0.0f, City_TexShift(mins.x, scale0), City_TexShift(mins.y, scale1), stats);
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_ROAD, scale0, scale1, 0.0f, City_TexShift(mins.x, scale0), City_TexShiftFloorYCenter(y, scale1), stats);
|
||||
}
|
||||
|
||||
static idEditorBrush* City_AddIntersectionRoadBrush(float x, float y, const cityBounds_t& bounds, cityStats_t& stats) {
|
||||
@@ -164,7 +193,7 @@ static idEditorBrush* City_AddIntersectionRoadBrush(float x, float y, const city
|
||||
const float scale = City_TexScale(CITY_ROAD_WIDTH);
|
||||
const idVec3 mins(x - roadHalf, y - roadHalf, bounds.mins.z);
|
||||
const idVec3 maxs(x + roadHalf, y + roadHalf, bounds.mins.z + 8.0f);
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_ROAD_INTERSECTION, scale, scale, 0.0f, City_TexShift(mins.x, scale), City_TexShift(mins.y, scale), stats);
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_ROAD_INTERSECTION, scale, scale, 0.0f, City_TexShiftFloorXCenter(x, scale), City_TexShiftFloorYCenter(y, scale), stats);
|
||||
}
|
||||
|
||||
static idEditorBrush* City_AddVerticalSidewalkBrush(float x0, float x1, float y0, float y1, const cityBounds_t& bounds, cityStats_t& stats) {
|
||||
@@ -183,10 +212,11 @@ static idEditorBrush* City_AddHorizontalSidewalkBrush(float x0, float x1, float
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_SIDEWALK, scale0, scale1, 0.0f, City_TexShift(mins.x, scale0), City_TexShift(mins.y, scale1), stats);
|
||||
}
|
||||
|
||||
static idEditorBrush* City_AddBuildingBrush(const idVec3& mins, const idVec3& maxs, const char* material, cityStats_t& stats) {
|
||||
const float scale0 = City_TexScale(CITY_BUILDING_TEXTURE_WIDTH);
|
||||
const float scale1 = City_TexScale(CITY_BUILDING_TEXTURE_HEIGHT);
|
||||
return City_AddWorldBrushUV(mins, maxs, material, scale0, scale1, 0.0f, 0.0f, City_TexShift(mins.z, scale1), stats);
|
||||
static idEditorBrush* City_AddSidewalkCornerBrush(float x0, float x1, float y0, float y1, const cityBounds_t& bounds, cityStats_t& stats) {
|
||||
const float scale = City_TexScale(CITY_SIDEWALK_WIDTH);
|
||||
const idVec3 mins(x0, y0, bounds.mins.z);
|
||||
const idVec3 maxs(x1, y1, bounds.mins.z + 8.0f);
|
||||
return City_AddWorldBrushUV(mins, maxs, CITY_MAT_MARS_SIDEWALK, scale, scale, 0.0f, City_TexShift(mins.x, scale), City_TexShift(maxs.y, scale), stats);
|
||||
}
|
||||
|
||||
static void City_SetVecKey(idEditorEntity* ent, const char* key, const idVec3& value) {
|
||||
@@ -219,6 +249,108 @@ static idEditorEntity* City_AddFixedEntity(const char* classname, const idVec3&
|
||||
return ent;
|
||||
}
|
||||
|
||||
static idEditorEntity* City_AddModelEntity(const cityMesh_t& mesh, const idVec3& origin, cityStats_t& stats) {
|
||||
idEditorEntity* ent = idEditorEntity::Entity_New();
|
||||
if (ent == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ent->brushes.onext = ent->brushes.oprev = &ent->brushes;
|
||||
ent->origin = origin;
|
||||
ent->SetKeyValue("classname", "func_static");
|
||||
ent->SetKeyValue("model", mesh.model.c_str());
|
||||
City_SetVecKey(ent, "origin", origin);
|
||||
ent->Entity_Name(false);
|
||||
ent->Entity_PostParse(&active_brushes);
|
||||
ent->Entity_AddToList(&entities);
|
||||
g_qeglobals.d_num_entities++;
|
||||
|
||||
Undo_EndEntity(ent);
|
||||
for (idEditorBrush* b = ent->brushes.onext; b != &ent->brushes; b = b->onext) {
|
||||
b->Brush_Build();
|
||||
Undo_EndBrush(b);
|
||||
stats.brushes++;
|
||||
}
|
||||
|
||||
stats.entities++;
|
||||
stats.buildings++;
|
||||
return ent;
|
||||
}
|
||||
|
||||
static bool City_AddMeshToCatalog(const char* modelName, idList<cityMesh_t>& meshes) {
|
||||
if (modelName == NULL || modelName[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
idRenderModel* model = renderModelManager->FindModel(modelName);
|
||||
if (model == NULL || model->IsDefaultModel()) {
|
||||
common->Printf("Automatic City Builder: could not load mesh '%s'\n", modelName);
|
||||
return false;
|
||||
}
|
||||
|
||||
cityMesh_t& mesh = meshes.Alloc();
|
||||
mesh.model = modelName;
|
||||
mesh.bounds = model->Bounds(NULL);
|
||||
mesh.size = mesh.bounds[1] - mesh.bounds[0];
|
||||
if (mesh.size.x <= 0.0f) {
|
||||
mesh.size.x = 1.0f;
|
||||
}
|
||||
if (mesh.size.y <= 0.0f) {
|
||||
mesh.size.y = 1.0f;
|
||||
}
|
||||
if (mesh.size.z <= 0.0f) {
|
||||
mesh.size.z = 1.0f;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void City_LoadMeshCatalog(idList<cityMesh_t>& meshes) {
|
||||
meshes.Clear();
|
||||
|
||||
const idDeclEntityDef* decl = static_cast<const idDeclEntityDef*>(declManager->FindType(DECL_ENTITYDEF, CITY_MESH_DEF, false));
|
||||
if (decl != NULL) {
|
||||
const idKeyValue* kv = decl->dict.MatchPrefix("mesh", NULL);
|
||||
while (kv != NULL) {
|
||||
City_AddMeshToCatalog(kv->GetValue().c_str(), meshes);
|
||||
kv = decl->dict.MatchPrefix("mesh", kv);
|
||||
}
|
||||
}
|
||||
|
||||
if (meshes.Num() == 0) {
|
||||
City_AddMeshToCatalog(CITY_FALLBACK_MESH, meshes);
|
||||
}
|
||||
}
|
||||
|
||||
static const cityMesh_t* City_ChooseMesh(const idList<cityMesh_t>& meshes, int blockX, int blockY, int lotX, int lotY) {
|
||||
if (meshes.Num() == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return &meshes[City_Hash(blockX * 41 + lotX, blockY * 43 + lotY, 97) % meshes.Num()];
|
||||
}
|
||||
|
||||
static float City_ModelLotSize(const idList<cityMesh_t>& meshes) {
|
||||
float lotSize = 0.0f;
|
||||
for (int i = 0; i < meshes.Num(); i++) {
|
||||
float required = meshes[i].size.x;
|
||||
if (meshes[i].size.y > required) {
|
||||
required = meshes[i].size.y;
|
||||
}
|
||||
required += CITY_MODEL_LOT_EXTRA;
|
||||
if (required > lotSize) {
|
||||
lotSize = required;
|
||||
}
|
||||
}
|
||||
if (lotSize <= 0.0f) {
|
||||
lotSize = CITY_ROAD_PITCH;
|
||||
}
|
||||
return lotSize;
|
||||
}
|
||||
|
||||
static float City_RequiredRoadPitch(const idList<cityMesh_t>& meshes) {
|
||||
const float clearHalf = CITY_ROAD_WIDTH * 0.5f + CITY_SIDEWALK_WIDTH;
|
||||
return City_ModelLotSize(meshes) + 2.0f * (CITY_BUILDING_EDGE_SETBACK + CITY_BUILDING_ALLEY + clearHalf);
|
||||
}
|
||||
|
||||
static cityBounds_t City_GetTargetBounds() {
|
||||
cityBounds_t bounds;
|
||||
bounds.mins.Set(-CITY_DEFAULT_HALF_SIZE, -CITY_DEFAULT_HALF_SIZE, 0.0f);
|
||||
@@ -335,6 +467,16 @@ static void City_AddHorizontalStreetEdges(float y, const cityBounds_t& bounds, c
|
||||
City_AddHorizontalStreetEdges(y, x0, bounds.maxs.x, bounds, stats);
|
||||
}
|
||||
|
||||
static void City_AddIntersectionSidewalkCorners(float x, float y, const cityBounds_t& bounds, cityStats_t& stats) {
|
||||
const float roadHalf = CITY_ROAD_WIDTH * 0.5f;
|
||||
const float sideHalf = roadHalf + CITY_SIDEWALK_WIDTH;
|
||||
|
||||
City_AddSidewalkCornerBrush(x - sideHalf, x - roadHalf, y - sideHalf, y - roadHalf, bounds, stats);
|
||||
City_AddSidewalkCornerBrush(x + roadHalf, x + sideHalf, y - sideHalf, y - roadHalf, bounds, stats);
|
||||
City_AddSidewalkCornerBrush(x - sideHalf, x - roadHalf, y + roadHalf, y + sideHalf, bounds, stats);
|
||||
City_AddSidewalkCornerBrush(x + roadHalf, x + sideHalf, y + roadHalf, y + sideHalf, bounds, stats);
|
||||
}
|
||||
|
||||
static void City_AddStreetSign(float x, float y, int avenue, int street, const cityBounds_t& bounds, cityStats_t& stats) {
|
||||
const float z0 = bounds.mins.z;
|
||||
const float poleX = x + CITY_ROAD_WIDTH * 0.5f + 44.0f;
|
||||
@@ -346,10 +488,14 @@ static void City_AddStreetSign(float x, float y, int avenue, int street, const c
|
||||
common->Printf("Automatic City Builder: street node A%i / S%i at %.0f %.0f\n", avenue + 1, street + 1, x, y);
|
||||
}
|
||||
|
||||
static void City_AddRoads(const cityBounds_t& bounds, idList<float>& roadX, idList<float>& roadY, cityStats_t& stats) {
|
||||
static void City_AddRoads(const cityBounds_t& bounds, const idList<cityMesh_t>& meshes, idList<float>& roadX, idList<float>& roadY, cityStats_t& stats) {
|
||||
const float roadHalf = CITY_ROAD_WIDTH * 0.5f;
|
||||
const int xRoads = City_ClampInt((int)((bounds.maxs.x - bounds.mins.x) / CITY_ROAD_PITCH), 2, 64);
|
||||
const int yRoads = City_ClampInt((int)((bounds.maxs.y - bounds.mins.y) / CITY_ROAD_PITCH), 2, 64);
|
||||
float roadPitch = City_RequiredRoadPitch(meshes);
|
||||
if (roadPitch <= 0.0f) {
|
||||
roadPitch = CITY_ROAD_PITCH;
|
||||
}
|
||||
const int xRoads = City_ClampInt((int)((bounds.maxs.x - bounds.mins.x) / roadPitch), 2, 64);
|
||||
const int yRoads = City_ClampInt((int)((bounds.maxs.y - bounds.mins.y) / roadPitch), 2, 64);
|
||||
const float xStep = (bounds.maxs.x - bounds.mins.x) / (float)xRoads;
|
||||
const float yStep = (bounds.maxs.y - bounds.mins.y) / (float)yRoads;
|
||||
|
||||
@@ -386,6 +532,7 @@ static void City_AddRoads(const cityBounds_t& bounds, idList<float>& roadX, idLi
|
||||
for (int x = 0; x < roadX.Num(); x++) {
|
||||
for (int y = 0; y < roadY.Num(); y++) {
|
||||
City_AddIntersectionRoadBrush(roadX[x], roadY[y], bounds, stats);
|
||||
City_AddIntersectionSidewalkCorners(roadX[x], roadY[y], bounds, stats);
|
||||
if (((x + y) & 1) == 0) {
|
||||
City_AddStreetSign(roadX[x], roadY[y], x, y, bounds, stats);
|
||||
}
|
||||
@@ -428,27 +575,7 @@ static void City_AddDirtLots(const cityBounds_t& bounds, const idList<float>& ro
|
||||
}
|
||||
}
|
||||
|
||||
static const char* City_BuildingMaterial(int x, int y) {
|
||||
static const char* materials[] = {
|
||||
CITY_MAT_MARS_BUILDING_01,
|
||||
CITY_MAT_MARS_BUILDING_02
|
||||
};
|
||||
return materials[City_Hash(x, y, 17) % (sizeof(materials) / sizeof(materials[0]))];
|
||||
}
|
||||
|
||||
static void City_AddBuilding(float minX, float minY, float maxX, float maxY, float baseZ, int gx, int gy, cityStats_t& stats) {
|
||||
const int floors = 2 + (City_Hash(gx, gy, 31) % 8);
|
||||
const float z0 = baseZ + 8.0f;
|
||||
const float z1 = z0 + 96.0f * floors + City_Random01(gx, gy, 23) * 64.0f;
|
||||
idVec3 mins(minX, minY, z0);
|
||||
idVec3 maxs(maxX, maxY, z1);
|
||||
|
||||
City_AddBuildingBrush(mins, maxs, City_BuildingMaterial(gx, gy), stats);
|
||||
City_AddWorldBrush(idVec3(minX - 8.0f, minY - 8.0f, z1), idVec3(maxX + 8.0f, maxY + 8.0f, z1 + 16.0f), CITY_MAT_MARS_DIRT, stats);
|
||||
stats.buildings++;
|
||||
}
|
||||
|
||||
static void City_AddBlockBuildings(const cityBounds_t& bounds, float minX, float minY, float maxX, float maxY, int blockX, int blockY, cityStats_t& stats) {
|
||||
static void City_AddBlockBuildings(const cityBounds_t& bounds, const idList<cityMesh_t>& meshes, float minX, float minY, float maxX, float maxY, int blockX, int blockY, cityStats_t& stats) {
|
||||
minX += CITY_BUILDING_EDGE_SETBACK;
|
||||
minY += CITY_BUILDING_EDGE_SETBACK;
|
||||
maxX -= CITY_BUILDING_EDGE_SETBACK;
|
||||
@@ -457,14 +584,20 @@ static void City_AddBlockBuildings(const cityBounds_t& bounds, float minX, float
|
||||
return;
|
||||
}
|
||||
|
||||
const int lotsX = City_ClampInt((int)((maxX - minX) / CITY_BUILDING_LOT_SIZE), 1, 2);
|
||||
const int lotsY = City_ClampInt((int)((maxY - minY) / CITY_BUILDING_LOT_SIZE), 1, 2);
|
||||
const float modelLotSize = City_ModelLotSize(meshes);
|
||||
const int lotsX = City_ClampInt((int)((maxX - minX) / modelLotSize), 1, 2);
|
||||
const int lotsY = City_ClampInt((int)((maxY - minY) / modelLotSize), 1, 2);
|
||||
const float stepX = (maxX - minX) / (float)lotsX;
|
||||
const float stepY = (maxY - minY) / (float)lotsY;
|
||||
|
||||
for (int y = 0; y < lotsY; y++) {
|
||||
for (int x = 0; x < lotsX; x++) {
|
||||
if ((City_Hash(blockX * 17 + x, blockY * 19 + y, 7) % 100) < 22) {
|
||||
if ((City_Hash(blockX * 17 + x, blockY * 19 + y, 7) % 100) < 8) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const cityMesh_t* mesh = City_ChooseMesh(meshes, blockX, blockY, x, y);
|
||||
if (mesh == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -472,26 +605,25 @@ static void City_AddBlockBuildings(const cityBounds_t& bounds, float minX, float
|
||||
float cellMinY = minY + y * stepY + CITY_BUILDING_ALLEY;
|
||||
float cellMaxX = minX + (x + 1) * stepX - CITY_BUILDING_ALLEY;
|
||||
float cellMaxY = minY + (y + 1) * stepY - CITY_BUILDING_ALLEY;
|
||||
if (cellMaxX - cellMinX < 96.0f || cellMaxY - cellMinY < 96.0f) {
|
||||
const float roomX = cellMaxX - cellMinX;
|
||||
const float roomY = cellMaxY - cellMinY;
|
||||
if (roomX < mesh->size.x + CITY_MODEL_LOT_EXTRA || roomY < mesh->size.y + CITY_MODEL_LOT_EXTRA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const float shrinkX = City_Random01(blockX * 31 + x, blockY * 37 + y, 11) * 24.0f;
|
||||
const float shrinkY = City_Random01(blockX * 31 + x, blockY * 37 + y, 13) * 24.0f;
|
||||
City_AddBuilding(
|
||||
cellMinX + shrinkX,
|
||||
cellMinY + shrinkY,
|
||||
cellMaxX - shrinkX,
|
||||
cellMaxY - shrinkY,
|
||||
bounds.mins.z,
|
||||
blockX * 10 + x,
|
||||
blockY * 10 + y,
|
||||
stats);
|
||||
const float centerX = (cellMinX + cellMaxX) * 0.5f;
|
||||
const float centerY = (cellMinY + cellMaxY) * 0.5f;
|
||||
const idVec3 modelCenter = (mesh->bounds[0] + mesh->bounds[1]) * 0.5f;
|
||||
idVec3 origin;
|
||||
origin.x = centerX - modelCenter.x;
|
||||
origin.y = centerY - modelCenter.y;
|
||||
origin.z = bounds.mins.z + 8.0f - mesh->bounds[0].z;
|
||||
City_AddModelEntity(*mesh, origin, stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void City_AddBuildings(const cityBounds_t& bounds, const idList<float>& roadX, const idList<float>& roadY, cityStats_t& stats) {
|
||||
static void City_AddBuildings(const cityBounds_t& bounds, const idList<float>& roadX, const idList<float>& roadY, const idList<cityMesh_t>& meshes, cityStats_t& stats) {
|
||||
const float clearHalf = CITY_ROAD_WIDTH * 0.5f + CITY_SIDEWALK_WIDTH;
|
||||
float y0 = bounds.mins.y;
|
||||
|
||||
@@ -501,7 +633,7 @@ static void City_AddBuildings(const cityBounds_t& bounds, const idList<float>& r
|
||||
|
||||
for (int x = 0; x <= roadX.Num(); x++) {
|
||||
const float x1 = (x == roadX.Num()) ? bounds.maxs.x : roadX[x] - clearHalf;
|
||||
City_AddBlockBuildings(bounds, x0, y0, x1, y1, x, y, stats);
|
||||
City_AddBlockBuildings(bounds, meshes, x0, y0, x1, y1, x, y, stats);
|
||||
|
||||
if (x < roadX.Num()) {
|
||||
x0 = roadX[x] + clearHalf;
|
||||
@@ -548,12 +680,14 @@ void Radiant_GenerateAutomaticCity() {
|
||||
|
||||
idList<float> roadX;
|
||||
idList<float> roadY;
|
||||
idList<cityMesh_t> meshes;
|
||||
const cityBounds_t bounds = City_GetTargetBounds();
|
||||
City_LoadMeshCatalog(meshes);
|
||||
|
||||
Select_Deselect();
|
||||
City_AddRoads(bounds, roadX, roadY, stats);
|
||||
City_AddRoads(bounds, meshes, roadX, roadY, stats);
|
||||
City_AddDirtLots(bounds, roadX, roadY, stats);
|
||||
City_AddBuildings(bounds, roadX, roadY, stats);
|
||||
City_AddBuildings(bounds, roadX, roadY, meshes, stats);
|
||||
City_AddPlayerStart(bounds, stats);
|
||||
City_AddPointLight(stats);
|
||||
|
||||
|
||||
@@ -69,7 +69,10 @@ void DrawRenderModel(idRenderModel* model, idVec3& origin, idMat3& axis, bool ca
|
||||
idVec3 v;
|
||||
|
||||
v = tri->verts[index].xyz * axis + origin;
|
||||
idVec3 normal = tri->verts[index].normal * axis;
|
||||
normal.Normalize();
|
||||
glTexCoord2f(tri->verts[index].st.x, tri->verts[index].st.y);
|
||||
glNormal3fv(normal.ToFloatPtr());
|
||||
glVertex3fv(v.ToFloatPtr());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@ This file is part of the IceTech GPL Source Code.
|
||||
class idDeclModelDef;
|
||||
class idDeclModelDefInterface;
|
||||
class idRenderModel;
|
||||
class idMaterial;
|
||||
class idAnim;
|
||||
class idMD5Anim;
|
||||
class idJointMat;
|
||||
@@ -23,6 +24,7 @@ class idJointMat;
|
||||
#define ID_MODELVIEW_DECLCOMBO 0x7A60
|
||||
#define ID_MODELVIEW_REFRESH 0x7A61
|
||||
#define ID_MODELVIEW_SHOWSKELETON 0x7A62
|
||||
#define ID_MODELVIEW_SHOWPLAYERMESH 0x7A7F
|
||||
#define ID_MODELVIEW_MESHTREE 0x7A63
|
||||
#define ID_MODELVIEW_ANIMLIST 0x7A64
|
||||
#define ID_MODELVIEW_RENDER 0x7A65
|
||||
@@ -36,6 +38,21 @@ class idJointMat;
|
||||
#define ID_MODELVIEW_TIMETEXT 0x7A6D
|
||||
#define ID_MODELVIEW_TRANSPORT 0x7A6E
|
||||
#define ID_MODELVIEW_REIMPORT 0x7A6F
|
||||
#define ID_MODELVIEW_FILE_IMPORTSTATICMESH 0x7A70
|
||||
#define ID_MODELVIEW_FILE_EXPORTMD5STATIC 0x7A72
|
||||
#define ID_MODELVIEW_SURFACEMATS 0x7A73
|
||||
#define ID_MODELVIEW_SETMATERIAL 0x7A74
|
||||
#define ID_MODELVIEW_CLEARMATERIAL 0x7A75
|
||||
#define ID_MODELVIEW_TRANSFORM_TX 0x7A76
|
||||
#define ID_MODELVIEW_TRANSFORM_TY 0x7A77
|
||||
#define ID_MODELVIEW_TRANSFORM_TZ 0x7A78
|
||||
#define ID_MODELVIEW_TRANSFORM_RX 0x7A79
|
||||
#define ID_MODELVIEW_TRANSFORM_RY 0x7A7A
|
||||
#define ID_MODELVIEW_TRANSFORM_RZ 0x7A7B
|
||||
#define ID_MODELVIEW_TRANSFORM_SX 0x7A7C
|
||||
#define ID_MODELVIEW_TRANSFORM_SY 0x7A7D
|
||||
#define ID_MODELVIEW_TRANSFORM_SZ 0x7A7E
|
||||
#define ID_MODELVIEW_INVERTNORMALS 0x7A80
|
||||
|
||||
#define WM_MODELVIEW_ANIMTIME_CHANGED (WM_APP + 0x260)
|
||||
|
||||
@@ -57,12 +74,14 @@ public:
|
||||
BOOL Create(CWnd* pParent, UINT nID);
|
||||
|
||||
void SetModelDecl(const idDeclModelDef* modelDecl);
|
||||
void SetStandaloneModel(idRenderModel* model, const char* displayName);
|
||||
void SetAnimation(const idMD5Anim* anim, int animLengthMS, int numFrames, const char* displayName);
|
||||
void SetAnimationTimeMS(int timeMS);
|
||||
void PlayAnimation();
|
||||
void PauseAnimation();
|
||||
void StopAnimation();
|
||||
void SetShowSkeleton(BOOL showSkeleton);
|
||||
void SetShowPlayerMesh(BOOL showPlayerMesh);
|
||||
void SetActive(BOOL active);
|
||||
void FocusRenderWindow();
|
||||
|
||||
@@ -71,6 +90,16 @@ public:
|
||||
int GetAnimationFrames() const;
|
||||
BOOL HasAnimation() const;
|
||||
BOOL IsPlaying() const;
|
||||
idRenderModel* CurrentModel() const;
|
||||
const idMaterial* SurfaceMaterialForSurface(int surfaceNum, const idMaterial* fallback) const;
|
||||
const idMaterial* SurfaceMaterialOverride(int surfaceNum) const;
|
||||
void SetSurfaceMaterialOverride(int surfaceNum, const idMaterial* material);
|
||||
void ClearSurfaceMaterialOverride(int surfaceNum);
|
||||
void ClearSurfaceMaterialOverrides();
|
||||
void SetStaticTransform(const idVec3& translate, const idVec3& rotate, const idVec3& scale);
|
||||
void ResetStaticTransform();
|
||||
bool InvertCurrentModelNormals();
|
||||
bool WriteCurrentMD5Static(const char* fileName) const;
|
||||
|
||||
private:
|
||||
HDC m_hDC;
|
||||
@@ -79,19 +108,31 @@ private:
|
||||
const idDeclModelDefInterface* m_modelDecl;
|
||||
idRenderModel* m_model;
|
||||
idRenderModel* m_cachedDynamicModel;
|
||||
const idDeclModelDefInterface* m_playerModelDecl;
|
||||
idRenderModel* m_playerModel;
|
||||
idRenderModel* m_cachedPlayerModel;
|
||||
|
||||
idJointMat* m_joints;
|
||||
idJointMat* m_playerJoints;
|
||||
int m_numJoints;
|
||||
int m_numPlayerJoints;
|
||||
BOOL m_haveAnimFrame;
|
||||
BOOL m_havePlayerFrame;
|
||||
|
||||
const idMD5Anim* m_anim;
|
||||
int m_animLengthMS;
|
||||
int m_animFrames;
|
||||
int m_animTimeMS;
|
||||
CString m_animDisplayName;
|
||||
CString m_standaloneDisplayName;
|
||||
idList<const idMaterial*> m_surfaceMaterialOverrides;
|
||||
idVec3 m_staticTranslate;
|
||||
idVec3 m_staticRotate;
|
||||
idVec3 m_staticScale;
|
||||
DWORD m_lastTick;
|
||||
|
||||
BOOL m_showSkeleton;
|
||||
BOOL m_showPlayerMesh;
|
||||
BOOL m_active;
|
||||
BOOL m_playing;
|
||||
BOOL m_dragging;
|
||||
@@ -107,19 +148,25 @@ private:
|
||||
void InitGL();
|
||||
void ShutdownGL();
|
||||
void FreeJointBuffer();
|
||||
void FreePlayerJointBuffer();
|
||||
void AllocateJointBuffer();
|
||||
void ResetCachedDynamicModel();
|
||||
void ResetCachedPlayerModel();
|
||||
void ResolveModelFromGameEdit();
|
||||
void ResolvePlayerReferenceModel();
|
||||
void UpdateAnimationFrame(BOOL forceResetCachedModel);
|
||||
void UpdatePlayerReferenceFrame(BOOL forceResetCachedModel);
|
||||
void NotifyAnimationTimeChanged();
|
||||
void FitCameraToModel();
|
||||
idVec3 PlayerReferenceOffset(idRenderModel* drawModel) const;
|
||||
void StepAnimation();
|
||||
|
||||
void DrawScene();
|
||||
void SetupCamera(const CRect& client);
|
||||
void DrawGrid();
|
||||
void DrawModel();
|
||||
void DrawRenderModel(idRenderModel* model, bool wireOnly);
|
||||
void DrawPlayerReferenceModel(idRenderModel* drawModel);
|
||||
void DrawRenderModel(idRenderModel* model, bool wireOnly, bool useMaterialOverrides = true, bool applyStaticTransform = true);
|
||||
void DrawSkeleton();
|
||||
void DrawOverlayText();
|
||||
|
||||
@@ -159,9 +206,19 @@ private:
|
||||
CButton m_btnRefresh;
|
||||
CButton m_btnReimport;
|
||||
CButton m_chkSkeleton;
|
||||
CButton m_chkPlayerMesh;
|
||||
CButton m_btnInvertNormals;
|
||||
CStatic m_lblMesh;
|
||||
CStatic m_lblStaticTransform;
|
||||
CStatic m_lblTransformCols[3];
|
||||
CStatic m_lblTransformRows[3];
|
||||
CEdit m_editTransform[3][3];
|
||||
CStatic m_lblSurfaceMaterials;
|
||||
CStatic m_lblAnim;
|
||||
CTreeCtrl m_treeMesh;
|
||||
CListBox m_listSurfaceMaterials;
|
||||
CButton m_btnSetSurfaceMaterial;
|
||||
CButton m_btnClearSurfaceMaterial;
|
||||
CListBox m_listAnims;
|
||||
CModelRenderWnd m_wndRender;
|
||||
CStatic m_transportPanel;
|
||||
@@ -173,20 +230,34 @@ private:
|
||||
HWND m_hMenuBar;
|
||||
|
||||
const idDeclModelDefInterface* m_modelDecl;
|
||||
idRenderModel* m_importedModel;
|
||||
CString m_importedModelPath;
|
||||
bool m_importedIsOBJ;
|
||||
bool m_importedIsMD5Static;
|
||||
BOOL m_active;
|
||||
bool m_inLayout;
|
||||
bool m_updatingTimeline;
|
||||
bool m_updatingStaticTransform;
|
||||
int m_timelineLengthMS;
|
||||
CPtrArray m_animItems;
|
||||
|
||||
private:
|
||||
void ApplyDarkTheme();
|
||||
void RedrawDarkControls();
|
||||
void ClearAnimationItems();
|
||||
void PopulateModelDecls();
|
||||
void LoadSelectedModelDecl();
|
||||
void ClearImportedModel();
|
||||
CString GetSelectedModelDeclFileName();
|
||||
void SetModelDecl(const idDeclModelDef* modelDecl);
|
||||
void PopulateStandaloneModelTree(idRenderModel* model, const char* displayName);
|
||||
void PopulateMeshTree();
|
||||
bool CurrentPreviewModelIsStatic() const;
|
||||
void ResetStaticTransformControls();
|
||||
void UpdateStaticTransformControls();
|
||||
void ReadStaticTransformControls();
|
||||
void PopulateSurfaceMaterialList();
|
||||
idRenderModel* CurrentPreviewModel() const;
|
||||
void PopulateAnimationList();
|
||||
void SelectAnimationItem(int itemIndex);
|
||||
void SelectModelDeclByName(const char* declName);
|
||||
@@ -206,11 +277,19 @@ protected:
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
afx_msg void OnDeclChanged();
|
||||
afx_msg void OnAnimChanged();
|
||||
afx_msg void OnSurfaceMaterialChanged();
|
||||
afx_msg void OnStaticTransformChanged();
|
||||
afx_msg void OnSetSurfaceMaterial();
|
||||
afx_msg void OnClearSurfaceMaterial();
|
||||
afx_msg void OnRefresh();
|
||||
afx_msg void OnReimportModel();
|
||||
afx_msg void OnNewMD5Decl();
|
||||
afx_msg void OnImportStaticMesh();
|
||||
afx_msg void OnExportMD5Static();
|
||||
afx_msg void OnAddAnimationFile();
|
||||
afx_msg void OnShowSkeleton();
|
||||
afx_msg void OnShowPlayerMesh();
|
||||
afx_msg void OnInvertNormals();
|
||||
afx_msg void OnPlay();
|
||||
afx_msg void OnPause();
|
||||
afx_msg void OnStop();
|
||||
|
||||
Reference in New Issue
Block a user