00001 #include "LandscapeScene.h"
00002 #include "TerminalObject.h"
00003 #include "DLODObject.h"
00004 #include "Cube.h"
00005 #include "Textures.h"
00006 #include "LandPatch.h"
00007
00008 void LandscapeScene::Init ()
00009 {
00010 Light * light;
00011 TerminalObject * sky;
00012 RawObject * textured_cube;
00013 GraphicalObject * one_patch;
00014 GraphicalObject * patch_group;
00015
00016
00017 textured_cube = new TexturedCube (5000.0f, Textures::GetId (T_SKY), false);
00018 sky = new TerminalObject (textured_cube);
00019 sky->position->SetConstantPosition (2500.0f, 2500.0f, 0.0f, 0.0f, 0.0f, 0.0f);
00020 AddObject (sky);
00021
00022
00023 PerlinNoise * perlin_height;
00024 int size_x, size_y;
00025 float stride;
00026
00027 printf ("generating height field...\n");
00028
00029 size_x = 513;
00030 size_y = 513;
00031 stride = 3.0f;
00032
00033 height_field = new float[size_x * size_y];
00034
00035 perlin_height = new PerlinNoise (size_x, size_y);
00036 perlin_height->SetParameters (16.0f, 0.5f, 8, true);
00037 perlin_height->GenerateNoise ();
00038 perlin_height->TransformAB (1.5f, 0.3f, PerlinNoise::LinearTransform);
00039 perlin_height->TransformAB (0.0f, 5.0f, PerlinNoise::RangeTransform);
00040 perlin_height->SmoothBorder (32);
00041 perlin_height->TransformAB (100.0f, 0.0f, PerlinNoise::LinearTransform);
00042 perlin_height->Export (height_field);
00043 delete perlin_height;
00044
00045 printf ("generating landscape...\n");
00046
00047
00048 one_patch = GeneratePart (height_field, 0, 7, 0, 7, size_x, size_y, stride);
00049 one_patch->CalculateRelativePositions ();
00050
00051 patch_group = ReplicatePatches (one_patch, (size_x - 1) * stride, 0 , 7, 0, 7);
00052 AddObject (patch_group);
00053
00054
00055 camera = new Camera ();
00056 camera->SetAttributes (45, 1.333, 1.0, 7000.0);
00057 camera->position->StartPath (0, 20.0f, 20.0f, 10.0f, 0.0f, 90.0f, 45.0f);
00058 camera->position->SetDuration (10000);
00059 camera->position->SetGlobalTransition (PP_SINE, 0.0f);
00060 camera->position->AddCheckpoint (120.0f, 20.0f, 100.0f, 0.0f, 20.0f, 45.0f);
00061 camera->position->SetDuration (40000);
00062 camera->position->SetGlobalTransition (PP_COSINE, 0.0f);
00063 camera->position->AddCheckpoint (1400.0f, 1200.0f, 100.0f, 0.0f, 20.0f, 45.0f);
00064 camera->position->SetDuration (40000);
00065 camera->position->SetTransitionModes (PP_LINEAR, PP_LINEAR, PP_LINEAR, PP_COSINE, PP_COSINE, PP_COSINE);
00066 camera->position->SetParameters (0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
00067 camera->position->AddCheckpoint (3600.0f, 3600.0f, 100.0f, 0.0f, 20.0f, 190.0f);
00068 camera->position->SetDuration (10000);
00069 camera->position->SetGlobalTransition (PP_SINE, 0.0f);
00070 camera->position->AddCheckpoint (4000.0f, 4000.0f, 100.0f, 0.0f, 20.0f, 220.0f);
00071
00072
00073
00074 light = new Light ();
00075 light->position->SetConstantPosition (20.0f, 20.0f, 400.0f, 0.0f, 0.0f, 0.0f);
00076 light->SetAmbient (0.2f, 0.2f, 0.2f, 1.0f);
00077 light->SetSpecular (1.0f, 1.0f, 1.0f, 1.0f);
00078 AddLight (light);
00079 }
00080
00081
00082 GraphicalObject * LandscapeScene::GeneratePart (float * height_field, int min_x, int max_x, int min_y, int max_y, int total_x, int total_y, float stride)
00083 {
00084 GroupObject * group;
00085 DLODObject * landscape;
00086 RawObject * patch;
00087
00088 if (min_x == max_x && min_y == max_y)
00089 {
00090
00091 patch = new LandPatch (height_field, 65, 65, 64 * min_x, 64 * min_y, total_x, total_y, stride, 1);
00092 patch->SetColor (0.2f, 0.7f, 0.1f, 1.0f);
00093
00094 landscape = new DLODObject (patch);
00095 landscape->position->SetConstantPosition (min_x * 64 * stride, min_y * 64 * stride, 0.0f, 0.0f, 0.0f, 0.0f);
00096
00097 patch = new LandPatch (height_field, 33, 33, 64 * min_x, 64 * min_y, total_x, total_y, stride, 2);
00098 patch->SetColor (0.2f, 0.7f, 0.1f, 1.0f);
00099 landscape->AddLevel (patch, 1000.0f);
00100
00101 patch = new LandPatch (height_field, 17, 17, 64 * min_x, 64 * min_y, total_x, total_y, stride, 4);
00102 patch->SetColor (0.2f, 0.7f, 0.1f, 1.0f);
00103 landscape->AddLevel (patch, 1800.0f);
00104
00105 patch = new LandPatch (height_field, 9, 9, 64 * min_x, 64 * min_y, total_x, total_y, stride, 8);
00106 patch->SetColor (0.2f, 0.7f, 0.1f, 1.0f);
00107 landscape->AddLevel (patch, 2800.0f);
00108
00109 patch = new LandPatch (height_field, 5, 5, 64 * min_x, 64 * min_y, total_x, total_y, stride, 16);
00110 patch->SetColor (0.2f, 0.7f, 0.1f, 1.0f);
00111 landscape->AddLevel (patch, 3800.0f);
00112
00113 patch = new LandPatch (height_field, 3, 3, 64 * min_x, 64 * min_y, total_x, total_y, stride, 32);
00114 patch->SetColor (0.2f, 0.7f, 0.1f, 1.0f);
00115 landscape->AddLevel (patch, 4800.0f);
00116
00117 return landscape;
00118 }
00119 else
00120 {
00121 group = new GroupObject ();
00122
00123 int x_boundary = (max_x - min_x) / 2;
00124 int y_boundary = (max_y - min_y) / 2;
00125
00126 group->AddChild (GeneratePart (height_field, min_x, min_x + x_boundary, min_y, min_y + y_boundary, total_x, total_y, stride));
00127 group->AddChild (GeneratePart (height_field, min_x + x_boundary + 1, max_x, min_y, min_y + y_boundary, total_x, total_y, stride));
00128 group->AddChild (GeneratePart (height_field, min_x, min_x + x_boundary, min_y + y_boundary + 1, max_y, total_x, total_y, stride));
00129 group->AddChild (GeneratePart (height_field, min_x + x_boundary + 1, max_x, min_y + y_boundary + 1, max_y, total_x, total_y, stride));
00130
00131 return group;
00132 }
00133 }
00134
00135 GroupObject * LandscapeScene::ReplicatePatches (GraphicalObject * one_patch, float size, int min_x, int max_x, int min_y, int max_y)
00136 {
00137 GroupObject * group;
00138 GroupObject * intermediate;
00139
00140 if (min_x == max_x && min_y == max_y)
00141 {
00142 intermediate = new GroupObject ();
00143 intermediate->AddChild (one_patch);
00144
00145 return intermediate;
00146 }
00147 else
00148 {
00149 group = new GroupObject ();
00150
00151 int x_boundary = (max_x - min_x) / 2;
00152 int y_boundary = (max_y - min_y) / 2;
00153
00154 intermediate = ReplicatePatches (one_patch, size, min_x, min_x + x_boundary, min_y, min_y + y_boundary);
00155 RandomRotate (intermediate, 0.0f, 0.0f, size * (x_boundary + 1));
00156 group->AddChild (intermediate);
00157
00158 intermediate = ReplicatePatches (one_patch, size, min_x + x_boundary + 1, max_x, min_y, min_y + y_boundary);
00159 RandomRotate (intermediate, size * (x_boundary + 1), 0.0f, size * (x_boundary + 1));
00160 group->AddChild (intermediate);
00161
00162 intermediate = ReplicatePatches (one_patch, size, min_x, min_x + x_boundary, min_y + y_boundary + 1, max_y);
00163 RandomRotate (intermediate, 0.0f, size * (y_boundary + 1), size * (x_boundary + 1));
00164 group->AddChild (intermediate);
00165
00166 intermediate = ReplicatePatches (one_patch, size, min_x + x_boundary + 1, max_x, min_y + y_boundary + 1, max_y);
00167 RandomRotate (intermediate, size * (x_boundary + 1), size * (y_boundary + 1), size * (x_boundary + 1));
00168 group->AddChild (intermediate);
00169
00170 return group;
00171 }
00172 }
00173
00174 void LandscapeScene::RandomRotate (GraphicalObject * patch, float x_offset, float y_offset, float size)
00175 {
00176 int rotation;
00177 float x_new, y_new;
00178
00179 rotation = rand ()%4;
00180 switch (rotation)
00181 {
00182 case 0: x_new = x_offset;
00183 y_new = y_offset;
00184 break;
00185 case 1: x_new = size + x_offset;
00186 y_new = y_offset;
00187 break;
00188 case 2: x_new = size + x_offset;
00189 y_new = size + y_offset;
00190 break;
00191 case 3: x_new = x_offset;
00192 y_new = size + y_offset;
00193 break;
00194 }
00195
00196 patch->position->SetConstantPosition (x_new, y_new, 0.0f, 0.0f, 0.0f, 90.0f * rotation);
00197 }