summaryrefslogtreecommitdiffhomepage
path: root/Stars45/Terrain.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-04-01 21:23:39 +0200
committerAki <please@ignore.pl>2022-04-01 21:23:39 +0200
commit3c487c5cd69c53d6fea948643c0a76df03516605 (patch)
tree72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /Stars45/Terrain.cpp
parent8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff)
downloadstarshatter-3c487c5cd69c53d6fea948643c0a76df03516605.zip
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.gz
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.bz2
Moved Stars45 to StarsEx
Diffstat (limited to 'Stars45/Terrain.cpp')
-rw-r--r--Stars45/Terrain.cpp559
1 files changed, 0 insertions, 559 deletions
diff --git a/Stars45/Terrain.cpp b/Stars45/Terrain.cpp
deleted file mode 100644
index 4d0a5f9..0000000
--- a/Stars45/Terrain.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-/* Starshatter: The Open Source Project
- Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors
- Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
- Copyright (c) 1997-2006, Destroyer Studios LLC.
-
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
-*/
-
-#include "Terrain.h"
-#include "TerrainApron.h"
-#include "TerrainClouds.h"
-#include "TerrainLayer.h"
-#include "TerrainPatch.h"
-#include "TerrainRegion.h"
-#include "Water.h"
-
-#include "CameraView.h"
-#include "Projector.h"
-#include "Scene.h"
-#include "Bitmap.h"
-#include "DataLoader.h"
-#include "Game.h"
-#include "MachineInfo.h"
-
-// +--------------------------------------------------------------------+
-
-int Terrain::detail_level = 3; // default = MEDIUM DETAIL
-
-const int PATCH_SIZE = 16;
-
-// +--------------------------------------------------------------------+
-
-Terrain::Terrain(TerrainRegion* trgn)
-: region(trgn), patches(0), water_patches(0), water(0),
-aprons(0), clouds(0), terrain_normals(0)
-{
- detail_frame = 0;
- datapath = "Galaxy/";
- terrain_texture = 0;
- apron_texture = 0;
- water_texture = 0;
-
- for (int i = 0; i < 2; i++) {
- cloud_texture[i] = 0;
- shade_texture[i] = 0;
- noise_texture[i] = 0;
- }
-
- if (region) {
- scale = region->LateralScale();
- mtnscale = region->MountainScale();
-
- ListIter<TerrainLayer> iter = region->GetLayers();
- while (++iter) {
- TerrainLayer* orig = iter.value();
- TerrainLayer* copy = new TerrainLayer;
- *copy = *orig;
- layers.append(copy);
- }
-
- layers.sort();
- }
-
- else {
- scale = 1;
- mtnscale = 1;
- }
-}
-
-// +--------------------------------------------------------------------+
-
-Terrain::~Terrain()
-{
- int i, j;
-
- if (patches)
- for (i = 0; i < subdivisions; i++)
- for (j = 0; j < subdivisions; j++)
- GRAPHIC_DESTROY(patches[i*subdivisions+j]);
-
- if (water_patches)
- for (i = 0; i < subdivisions; i++)
- for (j = 0; j < subdivisions; j++)
- GRAPHIC_DESTROY(water_patches[i*subdivisions+j]);
-
- if (aprons)
- for (i = 0; i < 8; i++)
- GRAPHIC_DESTROY(aprons[i]);
-
- if (clouds)
- for (i = 0; i < nclouds; i++)
- GRAPHIC_DESTROY(clouds[i]);
-
- if (water)
- for (i = 0; i < 6; i++)
- delete water[i];
-
- delete [] aprons;
- delete [] clouds;
- delete [] patches;
- delete [] water;
- delete [] terrain_normals;
-
- terrain_patch.ClearImage();
- terrain_apron.ClearImage();
-
- layers.destroy();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Terrain::BuildTerrain()
-{
- DataLoader* loader = DataLoader::GetLoader();
- loader->SetDataPath(datapath);
- loader->LoadBitmap( region->PatchName(), terrain_patch);
- loader->LoadBitmap( region->ApronName(), terrain_apron);
- loader->LoadTexture(region->PatchTexture(), terrain_texture);
- loader->LoadTexture(region->ApronTexture(), apron_texture);
- if (region->WaterTexture().length()) {
- loader->LoadTexture(region->WaterTexture(), water_texture);
-
- if (region->EnvironmentTexture(0).length() > 0) {
- loader->LoadTexture(region->EnvironmentTexture(0), env_texture[0]);
- loader->LoadTexture(region->EnvironmentTexture(1), env_texture[1]);
- loader->LoadTexture(region->EnvironmentTexture(2), env_texture[2]);
- loader->LoadTexture(region->EnvironmentTexture(3), env_texture[3]);
- loader->LoadTexture(region->EnvironmentTexture(4), env_texture[4]);
- loader->LoadTexture(region->EnvironmentTexture(5), env_texture[5]);
- }
- }
-
- loader->LoadTexture(region->CloudsHigh(), cloud_texture[0], Bitmap::BMP_TRANSLUCENT);
- loader->LoadTexture(region->CloudsLow(), cloud_texture[1], Bitmap::BMP_TRANSLUCENT);
- loader->LoadTexture(region->ShadesLow(), shade_texture[1], Bitmap::BMP_TRANSLUCENT);
-
- if (region->DetailTexture0().length())
- loader->LoadTexture(region->DetailTexture0(),noise_texture[0], Bitmap::BMP_TRANSLUCENT, false, true);
-
- if (region->DetailTexture1().length())
- loader->LoadTexture(region->DetailTexture1(),noise_texture[1], Bitmap::BMP_TRANSLUCENT, false, true);
-
- subdivisions = terrain_patch.Width() / PATCH_SIZE;
- patch_size = terrain_patch.Width() / subdivisions;
-
- BuildNormals();
-
- int i, j;
- int ntiles = terrain_patch.Width()/2 * terrain_patch.Height()/2;
- double dx = scale * patch_size;
- double dz = scale * patch_size;
- double offset = -subdivisions/2;
-
- if (water_texture) {
- water = new Water*[6];
- for (i = 0; i < 6; i++) {
- water[i] = new Water();
- int n = (1<<i) + 1;
- water[i]->Init(n, (float) (scale*patch_size), 90.0f);
- }
- }
-
- // load tile textures:
- for (i = 0; i < layers.size(); i++) {
- TerrainLayer* layer = layers.at(i);
-
- if (i < layers.size()-1)
- layer->max_height = layers.at(i+1)->min_height;
- else
- layer->max_height = 1e6;
-
- if (layer->tile_name.length())
- loader->LoadTexture(layer->tile_name, layer->tile_texture);
-
- if (layer->detail_name.length())
- loader->LoadTexture(layer->detail_name, layer->detail_texture);
- }
-
- patches = new TerrainPatch*[subdivisions*subdivisions];
-
- if (water_texture)
- water_patches = new TerrainPatch*[subdivisions*subdivisions];
-
- for (i = 0; i < subdivisions; i++) {
- for (j = 0; j < subdivisions; j++) {
- int j1 = subdivisions - j;
- Rect rect(j * patch_size, i * patch_size, patch_size, patch_size);
- Point p1((j1 + offset )*dx, 0, (i + offset )*dz);
- Point p2((j1 + offset+1)*dx, mtnscale, (i + offset+1)*dz);
-
- int index = i*subdivisions+j;
- patches[index] = new TerrainPatch(this, &terrain_patch, rect, p1, p2);
-
- if (water_texture && patches[index]->MinHeight() < 3)
- water_patches[index] = new TerrainPatch(this, rect, p1, p2, 30);
-
- else if (water_patches != 0)
- water_patches[index] = 0;
- }
- }
-
- int a = 0;
- dx = scale * terrain_patch.Width();
- dz = scale * terrain_patch.Height();
- offset = -3.0/2;
- double xoffset = offset + 1.0/16.0;
-
- aprons = new TerrainApron*[8];
-
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- int j1 = 2 - j;
- if (i != 1 || j1 != 1) {
- Rect rect(j * subdivisions, i * subdivisions, subdivisions, subdivisions);
- Point p1((j1 + xoffset )*dx, 0, (i + offset )*dz);
- Point p2((j1 + xoffset+1)*dx, mtnscale, (i + offset+1)*dz);
-
- aprons[a++] = new TerrainApron(this, &terrain_apron, rect, p1, p2);
- }
- }
- }
-
- Weather::STATE state = region->GetWeather().State();
-
- if (state == Weather::HIGH_CLOUDS || state == Weather::MODERATE_CLOUDS) {
- double altitude = region->CloudAltHigh();
- nclouds = 9;
-
- if (state == Weather::MODERATE_CLOUDS)
- nclouds *= 2;
-
- clouds = new TerrainClouds*[nclouds];
-
- a = 0;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- clouds[a] = new TerrainClouds(this, 0);
-
- double xloc = (j-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
- double yloc = (i-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
-
- clouds[a]->MoveTo(Point(xloc, altitude, yloc));
- a++;
- }
- }
-
- if (state == Weather::MODERATE_CLOUDS) {
- altitude = region->CloudAltLow();
-
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- clouds[a] = new TerrainClouds(this, 1);
-
- double xloc = (j-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
- double yloc = (i-1) * 75000 + (rand()/32768.0 - 0.5) * 50000;
-
- clouds[a]->MoveTo(Point(xloc, altitude, yloc));
- a++;
- }
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Terrain::BuildNormals()
-{
- if (terrain_normals) {
- delete [] terrain_normals;
- terrain_normals = 0;
- }
-
- int i, x, y;
-
- int w = terrain_patch.Width();
- int h = terrain_patch.Height();
- Color* pix = terrain_patch.HiPixels();
- BYTE* alt = new BYTE[h*w];
- int nverts = w * h;
- double scale = region->MountainScale() / (region->LateralScale() * 2.0);
-
- terrain_normals = new Vec3B[nverts];
-
- ZeroMemory(terrain_normals, sizeof(Vec3B) * nverts);
-
- for (i = 0; i < w; i++) {
- alt [ i] = 0;
- alt [(h-1)*w + i] = 0;
- terrain_normals[ i] = Vec3B(128,128,255);
- terrain_normals[(h-1)*w + i] = Vec3B(128,128,255);
- }
-
- for (i = 0; i < h; i++) {
- alt [i*w ] = 0;
- alt [i*w + (w-1)] = 0;
- terrain_normals[i*w ] = Vec3B(128,128,255);
- terrain_normals[i*w + (w-1)] = Vec3B(128,128,255);
- }
-
- for (y = 1; y < h-1; y++) {
- for (x = 1; x < w-1; x++) {
- alt[y*w+x] = (BYTE) pix[y*w+x].Red();
- }
- }
-
- for (y = 1; y < h-1; y++) {
- for (x = 1; x < w-1; x++) {
- double dx = (alt[y*w + (x-1)] - alt[y*w + (x+1)]) * scale +
- (alt[(y-1)*w + (x-1)] - alt[(y-1)*w + (x+1)]) * scale * 0.5 +
- (alt[(y+1)*w + (x-1)] - alt[(y+1)*w + (x+1)]) * scale * 0.5;
-
- double dy = (alt[(y-1)*w + x ] - alt[(y+1)*w + x ]) * scale +
- (alt[(y-1)*w + (x-1)] - alt[(y+1)*w + (x-1)]) * scale * 0.5 +
- (alt[(y-1)*w + (x+1)] - alt[(y+1)*w + (x+1)]) * scale * 0.5;
-
- Point norm(dx,dy,1);
- norm.Normalize();
-
- Vec3B* tnorm = &terrain_normals[y*w + x];
-
- tnorm->x = (BYTE) (norm.x * 127 + 128);
- tnorm->y = (BYTE) (norm.y * 127 + 128);
- tnorm->z = (BYTE) (norm.z * 127 + 128);
-
- double foo = dx/dy;
- }
- }
-
- delete [] alt;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Terrain::Activate(Scene& scene)
-{
- int i, j;
-
- StarSystem* system = region->System();
- if (system)
- datapath = system->GetDataPath();
-
- region->GetWeather().Update();
-
- if (!patches)
- BuildTerrain();
-
- if (patches) {
- for (i = 0; i < subdivisions; i++)
- for (j = 0; j < subdivisions; j++)
- if (patches[i*subdivisions+j])
- scene.AddGraphic(patches[i*subdivisions+j]);
- }
-
- if (water_patches) {
- for (i = 0; i < subdivisions; i++)
- for (j = 0; j < subdivisions; j++)
- if (water_patches[i*subdivisions+j])
- scene.AddGraphic(water_patches[i*subdivisions+j]);
- }
-
- if (aprons) {
- for (i = 0; i < 8; i++)
- if (aprons[i])
- scene.AddGraphic(aprons[i]);
- }
-
- if (clouds) {
- for (i = 0; i < nclouds; i++)
- if (clouds[i])
- scene.AddGraphic(clouds[i]);
- }
-}
-
-void
-Terrain::Deactivate(Scene& scene)
-{
- int i, j;
-
- if (patches) {
- for (i = 0; i < subdivisions; i++) {
- for (j = 0; j < subdivisions; j++) {
- TerrainPatch* p = patches[i*subdivisions+j];
-
- if (p) {
- p->DeletePrivateData();
- scene.DelGraphic(p);
- }
- }
- }
- }
-
- if (water_patches) {
- for (i = 0; i < subdivisions; i++) {
- for (j = 0; j < subdivisions; j++) {
- TerrainPatch* p = water_patches[i*subdivisions+j];
-
- if (p) {
- p->DeletePrivateData();
- scene.DelGraphic(p);
- }
- }
- }
- }
-
- if (aprons) {
- for (i = 0; i < 8; i++)
- if (aprons[i])
- scene.DelGraphic(aprons[i]);
- }
-
- if (clouds) {
- for (i = 0; i < nclouds; i++)
- if (clouds[i])
- scene.DelGraphic(clouds[i]);
- }
-
- StarSystem* system = region->System();
-
- // restore sunlight color and brightness on exit:
- if (system) {
- system->RestoreTrueSunColor();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Terrain::ExecFrame(double seconds)
-{
- if (water) {
- for (int i = 0; i < 6; i++) {
- if (water[i])
- water[i]->CalcWaves(seconds);
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Terrain::SelectDetail(Projector* projector)
-{
- if (!patches)
- return;
-
- if (detail_frame >= Game::GetInstance()->Frame())
- return;
-
- // compute detail map:
- int x, z;
-
- for (z = 0; z < subdivisions; z++) {
- for (x = 0; x < subdivisions; x++) {
- TerrainPatch* patch = patches[z*subdivisions + x];
- int ndetail = 0;
- Point loc = patch->Location();
- float radius = patch->Radius();
-
- if (loc.length() < 2*radius) {
- ndetail = detail_level;
- }
-
- else {
- double threshold = 4; //16;
-
- for (int level = 1; level <= detail_level; level++) {
- double feature_size = radius / (1 << level);
-
- if (projector->ApparentRadius(loc, (float) feature_size) > threshold)
- ndetail = level;
- }
- }
-
- patch->SetDetailLevel(ndetail);
-
- if (water_patches) {
- patch = water_patches[z*subdivisions + x];
- if (patch)
- patch->SetDetailLevel(ndetail);
- }
- }
- }
-
- // compute fog fade level:
- double hour = region->DayPhase();
-
- if (hour < 12)
- fog_fade = (hour) / 12.0;
- else
- fog_fade = (24-hour) / 12.0;
-
- fog_fade = fog_fade * (1-region->HazeFade()) + region->HazeFade();
-
- detail_frame = Game::GetInstance()->Frame();
-}
-
-// +--------------------------------------------------------------------+
-
-double
-Terrain::Height(double x, double y) const
-{
- double h = 0;
-
- if (patches) {
- int ix = (int) floor(x / (patch_size * scale));
- int iy = (int) floor(y / (patch_size * scale));
-
- double px = x - ix * patch_size * scale;
- double py = y - iy * patch_size * scale;
-
- ix = subdivisions/2 - ix;
- iy = subdivisions/2 + iy;
-
- TerrainPatch* patch = 0;
-
- if (ix >= 0 && ix < subdivisions &&
- iy >= 0 && iy < subdivisions)
- patch = patches[iy*subdivisions+ix];
-
- if (patch)
- h = patch->Height(px, py);
- }
-
- if (water_patches && h < 30)
- h = 30;
-
- return h;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Terrain::SetDetailLevel(int detail)
-{
- if (detail >= 1 && detail <= 4) {
-
- // limit detail on low memory machines:
- if (detail > 3 && MachineInfo::GetTotalRam() < 64)
- detail = 3;
-
- detail_level = detail;
- }
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-Terrain::IsFirstPatch(TerrainPatch* p) const
-{
- return (patches && *patches == p);
-} \ No newline at end of file