//Note: models get some ambient colour added when dark as the camera moves closer void CityOnPlanet::Render(Graphics::Renderer *r, const Camera *camera, const SpaceStation *station, const vector3d &viewCoords, const matrix4x4d &viewTransform, double illumination, double minIllumination) { matrix4x4d rot[4]; station->GetRotMatrix(rot[0]); // change detail level if necessary if (m_detailLevel != Pi::detail.cities) { RemoveStaticGeomsFromCollisionSpace(); AddStaticGeomsToCollisionSpace(); } rot[0] = viewTransform * rot[0]; for (int i=1; i<4; i++) { rot[i] = rot[0] * matrix4x4d::RotateYMatrix(M_PI*0.5*double(i)); } const Graphics::Frustum frustum = Graphics::Frustum::FromGLState(); //modelview seems to be always identity memset(&cityobj_params, 0, sizeof(LmrObjParams)); cityobj_params.time = Pi::game->GetTime(); for (std::vector<BuildingDef>::const_iterator i = m_buildings.begin(); i != m_buildings.end(); ++i) { if (!(*i).isEnabled) continue; vector3d pos = viewTransform * (*i).pos; if (!frustum.TestPoint(pos, (*i).clipRadius)) continue; const Color oldSceneAmbientColor = r->GetAmbientColor(); // fade conditions for models double fadeInEnd, fadeInLength; if (Graphics::AreShadersEnabled()) { fadeInEnd = 10.0; fadeInLength = 500.0; } else { fadeInEnd = 2000.0; fadeInLength = 6000.0; } FadeInModelIfDark(r, (*i).clipRadius, pos.Length(), fadeInEnd, fadeInLength, illumination, minIllumination); matrix4x4f _rot; for (int e=0; e<16; e++) _rot[e] = float(rot[(*i).rotation][e]); _rot[12] = float(pos.x); _rot[13] = float(pos.y); _rot[14] = float(pos.z); (*i).model->Render(_rot, &cityobj_params); // restore old ambient colour if (illumination <= minIllumination) r->SetAmbientColor(oldSceneAmbientColor); } }
void CityOnPlanet::Render(const SpaceStation *station, const vector3d &viewCoords, const matrix4x4d &viewTransform) { matrix4x4d rot[4]; station->GetRotMatrix(rot[0]); // change detail level if necessary if (m_detailLevel != Pi::detail.cities) { RemoveStaticGeomsFromCollisionSpace(); AddStaticGeomsToCollisionSpace(); } rot[0] = viewTransform * rot[0]; for (int i=1; i<4; i++) { rot[i] = rot[0] * matrix4x4d::RotateYMatrix(M_PI*0.5*double(i)); } GetFrustum(planes); memset(&cityobj_params, 0, sizeof(LmrObjParams)); // this f*****g rubbish needs to be moved into a function cityobj_params.argDoubles[1] = Pi::GetGameTime(); cityobj_params.argDoubles[2] = Pi::GetGameTime() / 60.0; cityobj_params.argDoubles[3] = Pi::GetGameTime() / 3600.0; cityobj_params.argDoubles[4] = Pi::GetGameTime() / (24*3600.0); for (std::vector<BuildingDef>::const_iterator i = m_buildings.begin(); i != m_buildings.end(); ++i) { if (!(*i).isEnabled) continue; vector3d pos = viewTransform * (*i).pos; /* frustum cull */ bool cull = false; for (int j=0; j<6; j++) { if (planes[j].DistanceToPoint(pos)+(*i).clipRadius < 0) { cull = true; break; } } if (cull) continue; matrix4x4f _rot; for (int e=0; e<16; e++) _rot[e] = float(rot[(*i).rotation][e]); _rot[12] = float(pos.x); _rot[13] = float(pos.y); _rot[14] = float(pos.z); (*i).model->Render(_rot, &cityobj_params); } }
void CityOnPlanet::Render(Graphics::Renderer *r, const SpaceStation *station, const vector3d &viewCoords, const matrix4x4d &viewTransform) { matrix4x4d rot[4]; station->GetRotMatrix(rot[0]); // change detail level if necessary if (m_detailLevel != Pi::detail.cities) { RemoveStaticGeomsFromCollisionSpace(); AddStaticGeomsToCollisionSpace(); } rot[0] = viewTransform * rot[0]; for (int i=1; i<4; i++) { rot[i] = rot[0] * matrix4x4d::RotateYMatrix(M_PI*0.5*double(i)); } Graphics::Frustum frustum = Graphics::Frustum::FromGLState(); //modelview seems to be always identity memset(&cityobj_params, 0, sizeof(LmrObjParams)); cityobj_params.time = Pi::game->GetTime(); for (std::vector<BuildingDef>::const_iterator i = m_buildings.begin(); i != m_buildings.end(); ++i) { if (!(*i).isEnabled) continue; vector3d pos = viewTransform * (*i).pos; if (!frustum.TestPoint(pos, (*i).clipRadius)) continue; matrix4x4f _rot; for (int e=0; e<16; e++) _rot[e] = float(rot[(*i).rotation][e]); _rot[12] = float(pos.x); _rot[13] = float(pos.y); _rot[14] = float(pos.z); (*i).model->Render(_rot, &cityobj_params); } }
CityOnPlanet::CityOnPlanet(Planet *planet, SpaceStation *station, Uint32 seed) { m_buildings.clear(); m_planet = planet; m_frame = planet->GetFrame(); m_detailLevel = Pi::detail.cities; /* Resolve city model numbers since it is a bit expensive */ if (!s_cityBuildingsInitted) { s_cityBuildingsInitted = true; for (int i=0; i<MAX_BUILDING_LISTS; i++) { lookupBuildingListModels(&s_buildingLists[i]); } } Aabb aabb; station->GetAabb(aabb); matrix4x4d m; station->GetRotMatrix(m); vector3d mx = m*vector3d(1,0,0); vector3d mz = m*vector3d(0,0,1); MTRand rand; rand.seed(seed); vector3d p = station->GetPosition(); vector3d p1, p2, p3, p4; double sizex = START_SEG_SIZE;// + rand.Int32((int)START_SEG_SIZE); double sizez = START_SEG_SIZE;// + rand.Int32((int)START_SEG_SIZE); // always have random shipyard buildings around the space station cityflavour[0].buildingListIdx = 0;//2; cityflavour[0].center = p; cityflavour[0].size = 500; for (int i=1; i<CITYFLAVOURS; i++) { cityflavour[i].buildingListIdx = MAX_BUILDING_LISTS>1 ? rand.Int32(MAX_BUILDING_LISTS-1) : 0; citybuildinglist_t *blist = &s_buildingLists[cityflavour[i].buildingListIdx]; double a = rand.Int32(-1000,1000); double b = rand.Int32(-1000,1000); cityflavour[i].center = p + a*mx + b*mz; cityflavour[i].size = rand.Int32(int(blist->minRadius), int(blist->maxRadius)); } for (int side=0; side<4; side++) { /* put buildings on all sides of spaceport */ switch(side) { case 3: p1 = p + mx*(aabb.min.x) + mz*aabb.min.z; p2 = p + mx*(aabb.min.x) + mz*(aabb.min.z-sizez); p3 = p + mx*(aabb.min.x+sizex) + mz*(aabb.min.z-sizez); p4 = p + mx*(aabb.min.x+sizex) + mz*(aabb.min.z); break; case 2: p1 = p + mx*(aabb.min.x-sizex) + mz*aabb.max.z; p2 = p + mx*(aabb.min.x-sizex) + mz*(aabb.max.z-sizez); p3 = p + mx*(aabb.min.x) + mz*(aabb.max.z-sizez); p4 = p + mx*(aabb.min.x) + mz*(aabb.max.z); break; case 1: p1 = p + mx*(aabb.max.x-sizex) + mz*aabb.max.z; p2 = p + mx*(aabb.max.x) + mz*aabb.max.z; p3 = p + mx*(aabb.max.x) + mz*(aabb.max.z+sizez); p4 = p + mx*(aabb.max.x-sizex) + mz*(aabb.max.z+sizez); break; default: case 0: p1 = p + mx*aabb.max.x + mz*aabb.min.z; p2 = p + mx*(aabb.max.x+sizex) + mz*aabb.min.z; p3 = p + mx*(aabb.max.x+sizex) + mz*(aabb.min.z+sizez); p4 = p + mx*aabb.max.x + mz*(aabb.min.z+sizez); break; } PutCityBit(rand, m, p1, p2, p3, p4); } AddStaticGeomsToCollisionSpace(); }