00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00026 #include "Scene.h"
00027 #include "DisplayDevice.h"
00028 #include "Inform.h"
00029 #include "DispCmds.h"
00030 #include "utilities.h"
00031 #include "FileRenderList.h"
00032 #include "FileRenderer.h"
00033 #include "ColorScaleTables.h"
00034
00035 static const int num_scalemethods = 36;
00036 static const ColorScale defScales[] = {
00037 { {1.0, 0.0, 0.0}, {1.0, 1.0, 1.0}, {0.0, 0.0, 1.0}, "RWB"},
00038 { {0.0, 0.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 0.0, 0.0}, "BWR"},
00039 { {1.0, 0.0, 0.0}, {0.5, 0.5, 0.5}, {0.0, 0.0, 1.0}, "RGryB"},
00040 { {0.0, 0.0, 1.0}, {0.5, 0.5, 0.5}, {1.0, 0.0, 0.0}, "BGryR"},
00041 { {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, "RGB"},
00042 { {0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, "BGR"},
00043 { {1.0, 0.0, 0.0}, {1.0, 1.0, 1.0}, {0.0, 1.0, 0.0}, "RWG"},
00044 { {0.0, 1.0, 0.0}, {1.0, 1.0, 1.0}, {1.0, 0.0, 0.0}, "GWR"},
00045 { {0.0, 1.0, 0.0}, {1.0, 1.0, 1.0}, {0.0, 0.0, 1.0}, "GWB"},
00046 { {0.0, 0.0, 1.0}, {1.0, 1.0, 1.0}, {0.0, 1.0, 0.0}, "BWG"},
00047 { {0.0, 0.0, 0.0}, {0.5, 0.5, 0.5}, {1.0, 1.0, 1.0}, "BlkW"},
00048 { {1.0, 1.0, 1.0}, {0.5, 0.5, 0.5}, {0.0, 0.0, 0.0}, "WBlk"},
00049
00050
00051 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "cividis"},
00052 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "viridis"},
00053 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "magma"},
00054 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "plasma"},
00055 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "inferno"},
00056
00057
00058 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L3"},
00059 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L8"},
00060 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L9"},
00061 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L16"},
00062 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L17"},
00063 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L18"},
00064 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L19"},
00065 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_L20"},
00066
00067
00068 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_C2"},
00069 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_C4"},
00070 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_C6"},
00071 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_C7"},
00072
00073
00074 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_I1"},
00075 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_I2"},
00076 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_I3"},
00077 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_D11"},
00078 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_D12"},
00079
00080
00081 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "turbo"},
00082 { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, "CET_R2"}
00083 };
00084
00085 static const char *colScaleMenuNames[] = {
00086 "RWB",
00087 "BWR",
00088 "RGryB",
00089 "BGryR",
00090 "RGB",
00091 "BGR",
00092 "RWG",
00093 "GWR",
00094 "GWB",
00095 "BWG",
00096 "BlkW",
00097 "WBlk",
00098
00099 "Sequential/cividis",
00100 "Sequential/viridis",
00101 "Sequential/magma",
00102 "Sequential/plasma",
00103 "Sequential/inferno",
00104
00105 "Linear/CET_L3",
00106 "Linear/CET_L8",
00107 "Linear/CET_L9",
00108 "Linear/CET_L16",
00109 "Linear/CET_L17",
00110 "Linear/CET_L18",
00111 "Linear/CET_L19",
00112 "Linear/CET_L20",
00113
00114 "Cyclic/CET_C2",
00115 "Cyclic/CET_C4",
00116 "Cyclic/CET_C6",
00117 "Cyclic/CET_C7",
00118
00119 "Isoluminant/CET_I1",
00120 "Isoluminant/CET_I2",
00121 "Isoluminant/CET_I3",
00122 "Isoluminant/CET_D11",
00123 "Isoluminant/CET_D12",
00124
00125 "Rainbow/Turbo",
00126 "Rainbow/CET_R2"
00127 };
00128
00129
00130 enum colorScaleType {
00131 SCALE_TYPE_TABULATED=0,
00132 SCALE_TYPE_TABULATED_SRGB=1,
00133 SCALE_TYPE_DIVERGENT=2
00134 };
00135
00136
00138 class ColorScaleTypeInfo {
00139 public:
00140 enum colorScaleType type;
00141 const float *colortable;
00142 int colortabsz;
00143
00144 #if 0
00145 int operator==(const ColorScale c) {
00146 return !memcmp(&c, this, sizeof(ColorScale));
00147 }
00148 #endif
00149 };
00150
00151
00152
00153 static const ColorScaleTypeInfo scaleTypes[] = {
00154 {SCALE_TYPE_DIVERGENT, NULL, 0},
00155 {SCALE_TYPE_DIVERGENT, NULL, 0},
00156 {SCALE_TYPE_DIVERGENT, NULL, 0},
00157 {SCALE_TYPE_DIVERGENT, NULL, 0},
00158 {SCALE_TYPE_DIVERGENT, NULL, 0},
00159 {SCALE_TYPE_DIVERGENT, NULL, 0},
00160 {SCALE_TYPE_DIVERGENT, NULL, 0},
00161 {SCALE_TYPE_DIVERGENT, NULL, 0},
00162 {SCALE_TYPE_DIVERGENT, NULL, 0},
00163 {SCALE_TYPE_DIVERGENT, NULL, 0},
00164 {SCALE_TYPE_DIVERGENT, NULL, 0},
00165 {SCALE_TYPE_DIVERGENT, NULL, 0},
00166
00167 {SCALE_TYPE_TABULATED, cividis_data, 255},
00168 {SCALE_TYPE_TABULATED, viridis_data, 255},
00169 {SCALE_TYPE_TABULATED, magma_data, 255},
00170 {SCALE_TYPE_TABULATED, plasma_data, 255},
00171 {SCALE_TYPE_TABULATED, inferno_data, 255},
00172
00173 {SCALE_TYPE_TABULATED, CET_L3_data, 255},
00174 {SCALE_TYPE_TABULATED, CET_L8_data, 255},
00175 {SCALE_TYPE_TABULATED, CET_L9_data, 255},
00176 {SCALE_TYPE_TABULATED, CET_L16_data, 255},
00177 {SCALE_TYPE_TABULATED, CET_L17_data, 255},
00178 {SCALE_TYPE_TABULATED, CET_L18_data, 255},
00179 {SCALE_TYPE_TABULATED, CET_L19_data, 255},
00180 {SCALE_TYPE_TABULATED, CET_L20_data, 255},
00181
00182 {SCALE_TYPE_TABULATED, CET_C2_data, 255},
00183 {SCALE_TYPE_TABULATED, CET_C4_data, 255},
00184 {SCALE_TYPE_TABULATED, CET_C6_data, 255},
00185 {SCALE_TYPE_TABULATED, CET_C7_data, 255},
00186
00187 {SCALE_TYPE_TABULATED, CET_I1_data, 255},
00188 {SCALE_TYPE_TABULATED, CET_I2_data, 255},
00189 {SCALE_TYPE_TABULATED, CET_I3_data, 255},
00190 {SCALE_TYPE_TABULATED, CET_D11_data, 255},
00191 {SCALE_TYPE_TABULATED, CET_D12_data, 255},
00192
00193 {SCALE_TYPE_TABULATED, turbo_srgb_data, 255},
00194 {SCALE_TYPE_TABULATED, CET_R2_data, 255}
00195 };
00196
00197
00198
00199
00200
00201 static const char *defColorNames[REGCLRS] = {
00202 "blue", "red", "gray", "orange",
00203 "yellow", "tan", "silver", "green",
00204 "white", "pink", "cyan", "purple",
00205 "lime", "mauve", "ochre", "iceblue",
00206
00207
00208 "black"
00209
00210 #if (REGCLRS > 17)
00211 ,"yellow2", "yellow3", "green2", "green3",
00212 "cyan2", "cyan3", "blue2", "blue3",
00213 "violet", "violet2", "magenta", "magenta2",
00214 "red2", "red3", "orange2", "orange3"
00215 #endif
00216
00217 };
00218
00219 const float Scene::defaultColor[] = {
00220 0.0f, 0.0f, 1.00f, 1.0f, 0.0f, 0.0f,
00221 0.35f, 0.35f, 0.35f, 1.0f, 0.5f, 0.0f,
00222 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.2f,
00223 0.6f, 0.6f, 0.6f, 0.0f, 1.0f, 0.0f,
00224 1.0f, 1.0f, 1.0f, 1.0f, 0.6f, 0.6f,
00225 0.25f, 0.75f, 0.75f, 0.65f, 0.0f, 0.65f,
00226 0.5f, 0.9f, 0.4f, 0.9f, 0.4f, 0.7f,
00227 0.5f, 0.3f, 0.0f, 0.5f, 0.5f, 0.75f,
00228
00229
00230 0.0f, 0.0f, 0.0f
00231
00232 #if (REGCLRS > 17)
00233 ,0.88f, 0.97f, 0.02f, 0.55f, 0.90f, 0.02f,
00234 0.00f, 0.90f, 0.04f, 0.00f, 0.90f, 0.50f,
00235 0.00f, 0.88f, 1.00f, 0.00f, 0.76f, 1.00f,
00236 0.02f, 0.38f, 0.67f, 0.01f, 0.04f, 0.93f,
00237 0.27f, 0.00f, 0.98f, 0.45f, 0.00f, 0.90f,
00238 0.90f, 0.00f, 0.90f, 1.00f, 0.00f, 0.66f,
00239 0.98f, 0.00f, 0.23f, 0.81f, 0.00f, 0.00f,
00240 0.89f, 0.35f, 0.00f, 0.96f, 0.72f, 0.00f
00241 #endif
00242
00243 };
00244
00245
00247 class DisplayColor : public Displayable {
00248 private:
00249 int colorCat;
00250 int dcindex;
00251 int dccolor;
00252 int changed;
00253
00254 protected:
00255 void do_color_changed(int cat) {
00256 if (cat == colorCat) {
00257 dccolor = scene->category_item_value(colorCat, dcindex);
00258 changed = 1;
00259 }
00260 }
00261 void do_color_rgb_changed(int color) {
00262 if (color == dccolor)
00263 changed = 1;
00264 }
00265
00266 public:
00267 DisplayColor(Displayable *d, const char *coloritemname, int colorindex)
00268 : Displayable(d), changed(0) {
00269
00270 colorCat = scene->category_index("Display");
00271 if (colorCat == -1) {
00272 colorCat = scene->add_color_category("Display");
00273 }
00274 dcindex = scene->add_color_item(colorCat, coloritemname, colorindex);
00275 do_color_changed(colorCat);
00276 }
00277 int color_changed() const { return changed; }
00278 void clear_changed() { changed = 0; }
00279 int color_id() const { return dccolor; }
00280 };
00281
00282
00284 Scene::Scene() : root(this) {
00285 set_background_mode(0);
00286 reset_lights();
00287
00288
00289 int i;
00290 for (i=BEGREGCLRS; i<REGCLRS; i++) {
00291 colorNames.add_name(defColorNames[i], i);
00292 set_color_value(i, defaultColor + 3L*i);
00293 }
00294
00295
00296 for (i=0; i<num_scalemethods; i++) {
00297 colorScales.append(defScales[i]);
00298 colorScaleMenuNames.append(colScaleMenuNames[i]);
00299 }
00300
00301 scaleActive = 0;
00302 scaleMin = 0.06f;
00303 scaleMid = 0.50f;
00304 scaleMax = 1.00f;
00305 scalePosterize = 0;
00306 scaleReverse = 0;
00307 create_colorscale();
00308
00309
00310 background = new DisplayColor(&root, "Background", REGBLACK);
00311 background_color_changed = 0;
00312 background_color_id = 0;
00313
00314
00315 backgradtop = new DisplayColor(&root, "BackgroundTop", REGBLACK);
00316 backgradtop_color_changed = 0;
00317 backgradtop_color_id = 0;
00318 backgradbot = new DisplayColor(&root, "BackgroundBot", REGBLUE2);
00319 backgradbot_color_changed = 0;
00320 backgradbot_color_id = 0;
00321
00322
00323 foreground = new DisplayColor(&root, "Foreground", REGWHITE);
00324 foreground_color_changed = 0;
00325 foreground_color_id = 0;
00326 }
00327
00329 Scene::~Scene(void) {
00330 for (int i=0; i<categories.num(); i++) delete categories.data(i);
00331 }
00332
00334
00335
00336 void Scene::set_background_mode(int mode) {
00337 backgroundmode = mode;
00338 backgroundmode_changed = 1;
00339 }
00340
00341
00342 int Scene::background_mode(void) {
00343 return backgroundmode;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352 static const float def_light_color[3] = { 1.0, 1.0, 1.0 };
00353 static const float def_light_pos[DISP_LIGHTS][3] = {
00354 { -0.1f, 0.1f, 1.0f }, { 1.0f, 2.0f, 0.5f },
00355 { -1.0f, 2.0f, -1.0f }, { -1.0f, -1.0f, 0.0f }
00356 };
00357 static const float def_adv_light_pos[DISP_LIGHTS][3] = {
00358 { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f },
00359 { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }
00360 };
00361
00362 static const int def_light_on[DISP_LIGHTS] = { TRUE, TRUE, FALSE, FALSE };
00363
00364 void Scene::define_light(int n, const float *color, const float *position) {
00365 if (n < 0 || n >= DISP_LIGHTS)
00366 return;
00367
00368 for (int i=0; i < 3; i++) {
00369 lightState[n].color[i] = color[i];
00370 lightState[n].pos[i] = position[i];
00371 }
00372 light_changed = 1;
00373 }
00374
00375 void Scene::activate_light(int n, int turnon) {
00376 if (n < 0 || n >= DISP_LIGHTS )
00377 return;
00378 lightState[n].on = turnon;
00379 light_changed = 1;
00380 }
00381
00382 void Scene::rotate_light(int n, float theta, char axis) {
00383 if (n < 0 || n >= DISP_LIGHTS)
00384 return;
00385 Matrix4 mat;
00386 mat.rot(theta,axis);
00387 mat.multpoint3d(lightState[n].pos,lightState[n].pos);
00388 light_changed = 1;
00389 }
00390
00391 void Scene::move_light(int n, const float *p) {
00392 if (n < 0 || n >= DISP_LIGHTS) return;
00393 for (int i=0; i<3; i++) lightState[n].pos[i] = p[i];
00394 light_changed = 1;
00395 }
00396
00397 const float *Scene::light_pos(int n) const {
00398 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00399 return lightState[n].pos;
00400 }
00401
00402 const float *Scene::light_pos_default(int n) const {
00403 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00404 return def_light_pos[n];
00405 }
00406
00407 const float *Scene::light_color(int n) const {
00408 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00409 return lightState[n].color;
00410 }
00411
00412 const float *Scene::light_color_default(int n) const {
00413 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00414 return def_light_color;
00415 }
00416
00417
00418 void Scene::define_adv_light(int n, const float *color,
00419 const float *position,
00420 float constant, float linear, float quad,
00421 float *spotdir,
00422 float fallstart, float fallend, int spoton) {
00423 if (n < 0 || n >= DISP_LIGHTS)
00424 return;
00425
00426 for (int i=0; i < 3; i++) {
00427 advLightState[n].color[i] = color[i];
00428 advLightState[n].pos[i] = position[i];
00429 advLightState[n].spotdir[i] = spotdir[i];
00430 }
00431 advLightState[n].constfactor = constant;
00432 advLightState[n].linearfactor = linear;
00433 advLightState[n].quadfactor = quad;
00434 advLightState[n].fallstart = fallstart;
00435 advLightState[n].fallend = fallend;
00436 advLightState[n].spoton = spoton;
00437 adv_light_changed = 1;
00438 }
00439
00440 void Scene::activate_adv_light(int n, int turnon) {
00441 if (n < 0 || n >= DISP_LIGHTS )
00442 return;
00443 advLightState[n].on = turnon;
00444 adv_light_changed = 1;
00445 }
00446
00447 void Scene::move_adv_light(int n, const float *p) {
00448 if (n < 0 || n >= DISP_LIGHTS) return;
00449 for (int i=0; i<3; i++)
00450 advLightState[n].pos[i] = p[i];
00451 adv_light_changed = 1;
00452 }
00453
00454 const float *Scene::adv_light_pos(int n) const {
00455 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00456 return advLightState[n].pos;
00457 }
00458
00459 const float *Scene::adv_light_pos_default(int n) const {
00460 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00461 return def_adv_light_pos[n];
00462 }
00463
00464 const float *Scene::adv_light_color(int n) const {
00465 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00466 return advLightState[n].color;
00467 }
00468
00469 const float *Scene::adv_light_color_default(int n) const {
00470 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00471 return def_light_color;
00472 }
00473
00474 void Scene::adv_light_attenuation(int n, float constant, float linear,
00475 float quad) {
00476 if (n < 0 || n >= DISP_LIGHTS) return;
00477 advLightState[n].constfactor = constant;
00478 advLightState[n].linearfactor = linear;
00479 advLightState[n].quadfactor = quad;
00480 }
00481
00482 void Scene::adv_light_get_attenuation(int n, float &constant, float &linear,
00483 float &quad) const {
00484 if (n < 0 || n >= DISP_LIGHTS) return;
00485 constant = advLightState[n].constfactor;
00486 linear = advLightState[n].linearfactor;
00487 quad = advLightState[n].quadfactor;
00488 }
00489
00490 void Scene::adv_light_spotlight(int n, float *spotdir, float fallstart,
00491 float fallend, int spoton) {
00492 if (n < 0 || n >= DISP_LIGHTS) return;
00493 advLightState[n].fallstart = fallstart;
00494 advLightState[n].fallend = fallend;
00495 advLightState[n].spoton = spoton;
00496 for (int i=0; i<3; i++)
00497 advLightState[n].spotdir[i] = spotdir[i];
00498 }
00499
00500 const float *Scene::adv_light_get_spotlight(int n, float &fallstart,
00501 float &fallend, int &spoton) const {
00502 if (n < 0 || n >= DISP_LIGHTS) return NULL;
00503 fallstart = advLightState[n].fallstart;
00504 fallend = advLightState[n].fallend;
00505 spoton = advLightState[n].spoton;
00506 return advLightState[n].spotdir;
00507 }
00508
00509 void Scene::reset_lights(void) {
00510 int i;
00511
00512
00513 for (i=0; i<DISP_LIGHTS; i++) {
00514 define_light(i, def_light_color, def_light_pos[i]);
00515 activate_light(i, def_light_on[i]);
00516 }
00517 light_changed = 1;
00518
00519
00520 for (i=0; i<DISP_LIGHTS; i++) {
00521 float spotdir[] = { 0.0f, 0.0f, 1.0f };
00522 define_adv_light(i, def_light_color, def_light_pos[i],
00523 1.0f, 0.0f, 0.0f,
00524 spotdir, 0.3f, 0.7f, 0);
00525 activate_adv_light(i, 0);
00526 }
00527 adv_light_changed = 1;
00528 }
00529
00530
00531
00532 int Scene::prepare() {
00533 background_color_changed = background->color_changed();
00534 background_color_id = background->color_id();
00535 background->clear_changed();
00536
00537 backgradtop_color_changed = backgradtop->color_changed();
00538 backgradtop_color_id = backgradtop->color_id();
00539 backgradtop->clear_changed();
00540
00541 backgradbot_color_changed = backgradbot->color_changed();
00542 backgradbot_color_id = backgradbot->color_id();
00543 backgradbot->clear_changed();
00544
00545 foreground_color_changed = foreground->color_changed();
00546 foreground_color_id = foreground->color_id();
00547 foreground->clear_changed();
00548
00549 return root.draw_prepare() || backgroundmode_changed || light_changed ||
00550 background_color_changed ||
00551 backgradtop_color_changed || backgradbot_color_changed ||
00552 foreground_color_changed;
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 void Scene::draw(DisplayDevice *display) {
00572 if (!display)
00573 return;
00574
00575 if (!display->is_renderer_process())
00576 return;
00577
00578
00579 if (backgroundmode_changed) {
00580 display->set_background_mode(backgroundmode);
00581 }
00582
00583
00584
00585 if (light_changed) {
00586
00587 for (int i=0; i<DISP_LIGHTS; i++) {
00588 display->do_define_light(i, lightState[i].color, lightState[i].pos);
00589 display->do_activate_light(i, lightState[i].on);
00590 }
00591 }
00592
00593 #if 0
00594
00595
00596
00597 if (adv_light_changed) {
00598
00599 for (int i=0; i<DISP_LIGHTS; i++) {
00600 display->do_define_light(i, lightState[i].color, lightState[i].pos);
00601 display->do_activate_light(i, lightState[i].on);
00602 }
00603 }
00604 #endif
00605
00606
00607 display->use_colors(colorData);
00608
00609
00610
00611
00612
00613
00614
00615 if (background_color_changed) {
00616 display->set_background(color_value(background_color_id));
00617 }
00618
00619
00620
00621 if (backgradtop_color_changed || backgradbot_color_changed) {
00622 display->set_backgradient(color_value(backgradtop->color_id()),
00623 color_value(backgradbot->color_id()));
00624 }
00625
00626
00627 display->prepare3D(TRUE);
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 if (display->forced_stereo_draws() && !(display->stereo_mode())) {
00640 display->left();
00641
00642 display->prepareOpaque();
00643 root.draw(display);
00644 if (display->prepareTrans()) {
00645 root.draw(display);
00646 }
00647
00648 display->right();
00649
00650 display->prepareOpaque();
00651 root.draw(display);
00652 if (display->prepareTrans()) {
00653 root.draw(display);
00654 }
00655 } else {
00656
00657 if (display->stereo_mode())
00658 display->left();
00659 else
00660 display->normal();
00661
00662
00663 display->prepareOpaque();
00664 root.draw(display);
00665
00666 if (display->prepareTrans()) {
00667 root.draw(display);
00668 }
00669
00670
00671 if (display->stereo_mode()) {
00672 display->right();
00673 display->prepareOpaque();
00674 root.draw(display);
00675
00676 if (display->prepareTrans()) {
00677 root.draw(display);
00678 }
00679 }
00680 }
00681
00682 display->render_done();
00683
00684
00685 display->update(TRUE);
00686 }
00687
00688
00689
00690
00691 int Scene::filedraw(FileRenderer *render, const char *filename,
00692 DisplayDevice *display) {
00693 int i;
00694
00695
00696 (*((DisplayDevice *)render)) = (*display);
00697
00698
00699 for (i=0; i<DISP_LIGHTS; i++) {
00700 if (lightState[i].on)
00701 render->do_define_light(i, lightState[i].color, lightState[i].pos);
00702 render->do_activate_light(i, lightState[i].on);
00703 }
00704
00705
00706 for (i=0; i<DISP_LIGHTS; i++) {
00707 if (advLightState[i].on)
00708 render->do_define_adv_light(i,
00709 advLightState[i].color,
00710 advLightState[i].pos,
00711 advLightState[i].constfactor,
00712 advLightState[i].linearfactor,
00713 advLightState[i].quadfactor,
00714 advLightState[i].spotdir,
00715 advLightState[i].fallstart,
00716 advLightState[i].fallend,
00717 advLightState[i].spoton);
00718 render->do_activate_adv_light(i, advLightState[i].on);
00719 }
00720
00721
00722 render->use_colors(colorData);
00723 render->set_background(color_value(background->color_id()));
00724 render->set_backgradient(color_value(backgradtop->color_id()),
00725 color_value(backgradbot->color_id()));
00726
00727
00728 if (!render->open_file(filename)) {
00729 return FALSE;
00730 }
00731
00732 render->prepare3D(TRUE);
00733
00734
00735 root.draw(render);
00736
00737
00738 render->render_done();
00739 render->update(TRUE);
00740
00741
00742 return TRUE;
00743 }
00744
00745
00746
00747 void Scene::draw_finished() {
00748
00749 backgroundmode_changed=0;
00750 light_changed = 0;
00751 adv_light_changed = 0;
00752 }
00753
00754
00755
00757
00758
00759 static float slope3_lower(float mid, float val) {
00760 if (val > mid) return 0.0f;
00761 if (mid == 0) return 1.0f;
00762 return (1.0f - val / mid);
00763 }
00764
00765
00766 static float slope3_upper(float mid, float val) {
00767 if (val < mid) return 0.0f;
00768 if (mid == 1) return 1.0f;
00769 return (1.0f - (1.0f - val) / (1.0f - mid));
00770 }
00771
00772
00773 static float slope3_middle(float mid, float val) {
00774 if (val < mid) {
00775 return val / mid;
00776 }
00777 if (val > mid) {
00778 return (1-val) / (1-mid);
00779 }
00780 return 1.0;
00781 }
00782
00783
00784
00785 static void scale_color(const float *lowRGB, const float *midRGB,
00786 const float *highRGB,
00787 float mid, float val, float scaleMin, float *rgb) {
00788 float w1 = slope3_lower(mid, val);
00789 float w2 = slope3_middle(mid, val);
00790 float w3 = slope3_upper(mid, val);
00791 float wsum = (w1 + w2 + w3);
00792
00793 rgb[0] = (lowRGB[0]*w1 + midRGB[0]*w2 + highRGB[0]*w3) / wsum + scaleMin;
00794 rgb[1] = (lowRGB[1]*w1 + midRGB[1]*w2 + highRGB[1]*w3) / wsum + scaleMin;
00795 rgb[2] = (lowRGB[2]*w1 + midRGB[2]*w2 + highRGB[2]*w3) / wsum + scaleMin;
00796
00797 clamp_color(rgb);
00798 }
00799
00800 void Scene::create_colorscale() {
00801 const ColorScale &scale = colorScales[scaleActive];
00802
00803 if (scalePosterize <= 1)
00804 scalePosterize = 0;
00805
00806 int maxidx = MAPCLRS - 1;
00807 float fmaxidx_inv = 1.0f / float(maxidx);
00808 float fpost_inv = 1.0f / float(scalePosterize - 1);
00809
00810 int i;
00811 switch (scaleTypes[scaleActive].type) {
00812 case SCALE_TYPE_DIVERGENT:
00813 for (i=0; i<=maxidx; i++) {
00814 int idx = (scaleReverse) ? (maxidx-i) : i;
00815 float *rcol = colorData + 3L*(BEGMAP + idx);
00816 float relpos = float(i) * fmaxidx_inv;
00817
00818 relpos = (scalePosterize) ? (int(relpos * scalePosterize) * fpost_inv) : relpos;
00819
00820 scale_color(scale.min, scale.mid, scale.max,
00821 scaleMid, relpos, scaleMin, rcol);
00822 }
00823 break;
00824
00825 case SCALE_TYPE_TABULATED:
00826 case SCALE_TYPE_TABULATED_SRGB:
00827 const float *ctab = scaleTypes[scaleActive].colortable;
00828 if (ctab == NULL) {
00829 printf("color tab NULL!\n");
00830 }
00831
00832 for (i=0; i<=maxidx; i++) {
00833 int idx = (scaleReverse) ? (maxidx-i) : i;
00834 float *rcol = colorData + 3L*(BEGMAP + idx);
00835 float relpos = float(i) / float(MAPCLRS-1);
00836
00837 relpos = (scalePosterize) ? (int(relpos * scalePosterize) * fpost_inv) : relpos;
00838
00839 int tabidx = int(scaleTypes[scaleActive].colortabsz * relpos);
00840 if (tabidx > scaleTypes[scaleActive].colortabsz)
00841 tabidx = scaleTypes[scaleActive].colortabsz;
00842
00843 rcol[0] = ctab[3*tabidx ];
00844 rcol[1] = ctab[3*tabidx + 1];
00845 rcol[2] = ctab[3*tabidx + 2];
00846 }
00847
00848
00849
00850 if (scaleTypes[scaleActive].type == SCALE_TYPE_TABULATED_SRGB) {
00851 for (i=0; i<=maxidx; i++) {
00852 float *rcol = colorData + 3L*(BEGMAP + i);
00853 rcol[0] = powf(rcol[0], 2.2f);
00854 rcol[1] = powf(rcol[1], 2.2f);
00855 rcol[2] = powf(rcol[2], 2.2f);
00856 }
00857 }
00858 break;
00859 }
00860
00861 root.color_scale_changed();
00862 }
00863
00864
00865 int Scene::colorscale_type(int index) {
00866 if (index < 0 || index >= num_scalemethods)
00867 return 0;
00868 return (scaleTypes[scaleActive].type != SCALE_TYPE_TABULATED);
00869 }
00870
00871
00872 int Scene::nearest_index(float r, float g, float b) const {
00873 const float *rcol = color_value(BEGREGCLRS);
00874 float lsq = r - rcol[0]; lsq *= lsq;
00875 float tmp = g - rcol[1]; lsq += tmp * tmp;
00876 tmp = b - rcol[2]; lsq += tmp * tmp;
00877 float best = lsq;
00878 int bestidx = BEGREGCLRS;
00879 for (int n= BEGREGCLRS+1; n < (BEGREGCLRS + REGCLRS); n++) {
00880 rcol = color_value(n);
00881 lsq = r - rcol[0]; lsq *= lsq;
00882 tmp = g - rcol[1]; lsq += tmp * tmp;
00883 tmp = b - rcol[2]; lsq += tmp * tmp;
00884 if (lsq < best) {
00885 best = lsq;
00886 bestidx = n;
00887 }
00888 }
00889 return bestidx;
00890 }
00891
00892 int Scene::get_colorscale_colors(int whichScale,
00893 float min[3], float mid[3], float max[3]) {
00894 if (whichScale < 0 || whichScale >= colorScales.num())
00895 return FALSE;
00896 const ColorScale &scale = colorScales[whichScale];
00897 for (int i=0; i<3; i++) {
00898 min[i] = scale.min[i];
00899 mid[i] = scale.mid[i];
00900 max[i] = scale.max[i];
00901 }
00902 return TRUE;
00903 }
00904
00905 int Scene::set_colorscale_colors(int whichScale,
00906 const float min[3], const float mid[3], const float max[3]) {
00907 if (whichScale < 0 || whichScale >= colorScales.num())
00908 return FALSE;
00909 ColorScale &scale = colorScales[whichScale];
00910 for (int i=0; i<3; i++) {
00911 scale.min[i] = min[i];
00912 scale.mid[i] = mid[i];
00913 scale.max[i] = max[i];
00914 }
00915 create_colorscale();
00916 return TRUE;
00917 }
00918