00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <string.h>
00024 #include "Displayable.h"
00025 #include "DispCmds.h"
00026 #include "PickList.h"
00027 #include "utilities.h"
00028 #include "VMDApp.h"
00029 #include "DisplayDevice.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 void *Displayable::operator new(size_t n) {
00071 return vmd_alloc(n);
00072 }
00073
00074 void Displayable::operator delete(void *p, size_t) {
00075 vmd_dealloc(p);
00076 }
00077
00078 Displayable::Displayable(Scene *s) : scene(s) {
00079
00080 parent = NULL;
00081 scale = 1;
00082 globt[0] = globt[1] = globt[2] = 0;
00083 centt[0] = centt[1] = centt[2] = 0;
00084
00085
00086 isOn = TRUE;
00087 doCent = doRot = doGlob = doScale = TRUE;
00088 do_create();
00089 }
00090
00091 Displayable::Displayable(Displayable *pops) : scene(pops->scene) {
00092
00093 _needUpdate = 1;
00094 parent = pops;
00095
00096
00097 vec_copy(centt, parent->centt);
00098 rotm = parent->rotm;
00099 vec_copy(globt, parent->globt);
00100 scale = parent->scale;
00101 tm = parent->tm;
00102
00103 isOn = parent->displayed();
00104 doCent = parent->doCent;
00105 doRot = parent->doRot;
00106 doGlob = parent->doGlob;
00107 doScale = parent->doScale;
00108
00109
00110 do_create();
00111
00112
00113 cmdList->ambient = parent->cmdList->ambient;
00114 cmdList->specular = parent->cmdList->specular;
00115 cmdList->diffuse = parent->cmdList->diffuse;
00116 cmdList->shininess = parent->cmdList->shininess;
00117 cmdList->opacity = parent->cmdList->opacity;
00118 cmdList->outline = parent->cmdList->outline;
00119 cmdList->outlinewidth = parent->cmdList->outlinewidth;
00120 cmdList->transmode = parent->cmdList->transmode;
00121 cmdList->materialtag = parent->cmdList->materialtag;
00122
00123
00124 cmdList->cacheskip = parent->cmdList->cacheskip;
00125
00126
00127 parent->add_child(this);
00128 }
00129
00130
00131
00132 void Displayable::do_create() {
00133
00134 children = (Displayable **)vmd_alloc(16*sizeof(Displayable*));
00135 num_children = 0;
00136 max_children = 16;
00137
00138
00139 cmdList = new VMDDisplayList;
00140
00141
00142 needMatrixRecalc = TRUE;
00143 isFixed = FALSE;
00144
00145
00146 cmdList->mat = tm;
00147
00148 }
00149
00150
00151 void Displayable::reset_disp_list(void) {
00152 _needUpdate = 1;
00153
00154
00155
00156 cmdList->reset_and_free(VMDApp::get_repserialnum());
00157 }
00158
00159
00160 Displayable::~Displayable(void) {
00161
00162 while(num_children > 0)
00163
00164
00165 delete child(0);
00166
00167 cmdList->reset_and_free(0);
00168 delete cmdList;
00169
00170
00171 if (parent)
00172 parent->remove_child(this);
00173
00174 vmd_dealloc(children);
00175 }
00176
00177
00179
00180
00181
00182
00183 void Displayable::recalc_mat(void) {
00184 if (needMatrixRecalc) {
00185 _needUpdate = 1;
00186 tm.identity();
00187 tm.translate(globt);
00188 tm.multmatrix(rotm);
00189 tm.scale(scale);
00190 tm.translate(centt);
00191
00192 cmdList->mat = tm;
00193
00194 needMatrixRecalc = FALSE;
00195 }
00196
00197
00198 for (int i=0; i < num_children; i++)
00199 child(i)->recalc_mat();
00200 }
00201
00203
00204
00205 void Displayable::off(void) {
00206 isOn = FALSE;
00207 _needUpdate = 1;
00208 }
00209
00210 void Displayable::on(void) {
00211 isOn = TRUE;
00212 _needUpdate = 1;
00213 }
00214
00215
00216 void Displayable::add_child(Displayable *d) {
00217
00218
00219 children[num_children++] = d;
00220 if (num_children == max_children) {
00221 void *tmp = vmd_alloc(max_children*2*sizeof(Displayable*));
00222 memcpy(tmp,children,max_children*sizeof(Displayable*));
00223 vmd_dealloc(children);
00224 children = (Displayable **)tmp;
00225 max_children *= 2;
00226 }
00227 }
00228
00229
00230
00231 int Displayable::remove_child(Displayable *d) {
00232
00233 int n = child_index(d);
00234 if (n >= 0) {
00235
00236 for (int i=n; i<num_children-1; i++) {
00237 children[i] = children[i+1];
00238 }
00239 num_children--;
00240 _needUpdate = 1;
00241 return TRUE;
00242 }
00243 return FALSE;
00244 }
00245
00246
00247
00248
00249
00250
00251 void Displayable::prepare() { }
00252
00253
00254 int Displayable::draw_prepare() {
00255 int needupdate;
00256
00257 if (parent == NULL)
00258 recalc_mat();
00259
00260 prepare();
00261
00262 needupdate = _needUpdate;
00263
00264
00265 for (int i=0; i < num_children; i++)
00266 needupdate |= child(i)->draw_prepare();
00267
00268
00269
00270
00271 _needUpdate = 0;
00272 return needupdate;
00273 }
00274
00275
00276 void Displayable::draw(DisplayDevice *d) const {
00277
00278 if (isOn) {
00279 d->render(cmdList);
00280 for (int i=0; i<num_children; i++)
00281 child(i)->draw(d);
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 void Displayable::reset_transformation(void) {
00292
00293 if (scaling()) scale=1;
00294 if (rotating()) { rotm.identity(); }
00295 if (glob_translating()) globt[0] = globt[1] = globt[2] = 0;
00296 if (cent_translating()) centt[0] = centt[1] = centt[2] = 0;
00297 need_matrix_recalc();
00298
00299
00300 for (int i=0; i < num_children; i++)
00301 child(i)->reset_transformation();
00302 }
00303
00304 void Displayable::set_scale(float s) {
00305 if (fixed()) return;
00306
00307
00308 for (int i=0; i < num_children; i++)
00309 child(i)->set_scale(s);
00310
00311 if (!scaling()) return;
00312 scale = s;
00313 need_matrix_recalc();
00314 }
00315
00316 void Displayable::mult_scale(float s) {
00317 if (fixed()) return;
00318
00319
00320 for (int i=0; i < num_children; i++)
00321 child(i)->mult_scale(s);
00322
00323 if (!scaling()) return;
00324 scale *= s;
00325 need_matrix_recalc();
00326 }
00327
00328 void Displayable::add_rot(float x, char axis) {
00329 if (fixed()) return;
00330
00331
00332 for (int i=0; i < num_children; i++)
00333 child(i)->add_rot(x, axis);
00334
00335 if (!rotating()) return;
00336
00337
00338 Matrix4 mat;
00339 mat.rot(x, axis);
00340 mat.multmatrix(rotm);
00341 rotm = mat;
00342 need_matrix_recalc();
00343 }
00344
00345 void Displayable::set_rot(float x, char axis) {
00346 if (fixed()) return;
00347
00348
00349 for (int i=0; i < num_children; i++)
00350 child(i)->set_rot(x, axis);
00351
00352 if (!rotating()) return;
00353
00354 rotm.identity();
00355 rotm.rot(x,axis);
00356 need_matrix_recalc();
00357 }
00358
00359 void Displayable::add_rot(const Matrix4 &m) {
00360 if (fixed()) return;
00361
00362
00363 for (int i=0; i < num_children; i++)
00364 child(i)->add_rot(m);
00365
00366 if (!rotating()) return;
00367 Matrix4 mat(m);
00368 mat.multmatrix(rotm);
00369 rotm = mat;
00370 need_matrix_recalc();
00371 }
00372
00373 void Displayable::set_rot(const Matrix4 &m) {
00374 if (fixed()) return;
00375
00376
00377 for (int i=0; i < num_children; i++)
00378 child(i)->set_rot(m);
00379
00380 if (!rotating()) return;
00381 rotm = m;
00382 need_matrix_recalc();
00383 }
00384
00385 void Displayable::set_glob_trans(float x, float y, float z) {
00386 if (fixed()) return;
00387
00388
00389 for (int i=0; i < num_children; i++)
00390 child(i)->set_glob_trans(x, y, z);
00391
00392 if (!glob_translating()) return;
00393 globt[0] = x;
00394 globt[1] = y;
00395 globt[2] = z;
00396 need_matrix_recalc();
00397 }
00398
00399 void Displayable::add_glob_trans(float x, float y, float z) {
00400 if (fixed()) return;
00401
00402
00403 for (int i=0; i < num_children; i++)
00404 child(i)->add_glob_trans(x, y, z);
00405
00406 if (!glob_translating()) return;
00407 globt[0] += x;
00408 globt[1] += y;
00409 globt[2] += z;
00410 need_matrix_recalc();
00411 }
00412
00413 void Displayable::set_cent_trans(float x, float y, float z) {
00414
00415 for (int i=0; i < num_children; i++)
00416 child(i)->set_cent_trans(x, y, z);
00417
00418 if (!cent_translating()) return;
00419 centt[0] = x;
00420 centt[1] = y;
00421 centt[2] = z;
00422 need_matrix_recalc();
00423 }
00424
00425 void Displayable::add_cent_trans(float x, float y, float z) {
00426
00427 for (int i=0; i < num_children; i++)
00428 child(i)->add_cent_trans(x, y, z);
00429
00430 if (!cent_translating()) return;
00431 centt[0] += x;
00432 centt[1] += y;
00433 centt[2] += z;
00434 recalc_mat();
00435 }
00436
00437 void Displayable::change_center(float x, float y, float z)
00438 {
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 float p[4], g[4], ident[4], m[4];
00459 ident[0]=0.0; ident[1] = 0.0; ident[2]=0.0; ident[3]=1.0;
00460 p[0]=x; p[1]=y; p[2]=z; p[3]=1.0;
00461
00462
00463 tm.multpoint4d(p,g);
00464
00465
00466 Matrix4 M(rotm);
00467 M.scale(scale);
00468 M.multpoint4d(ident, m);
00469
00470
00471 set_cent_trans(-x, -y, -z);
00472
00473
00474 set_glob_trans(g[0]-m[0], g[1]-m[1], g[2]-m[2]);
00475 }
00476
00477 void Displayable::change_material(const Material *mat) {
00478 _needUpdate = 1;
00479 cmdList->ambient = mat->ambient;
00480 cmdList->specular = mat->specular;
00481 cmdList->diffuse = mat->diffuse;
00482 cmdList->shininess = mat->shininess;
00483 cmdList->opacity = mat->opacity;
00484 cmdList->outline = mat->outline;
00485 cmdList->outlinewidth = mat->outlinewidth;
00486 cmdList->transmode = mat->transmode;
00487 cmdList->materialtag = mat->ind;
00488 }
00489
00490 void Displayable::cacheskip(int onoff) {
00491 cmdList->cacheskip = onoff;
00492 }
00493
00494 int Displayable::curr_material() const {
00495 return cmdList->materialtag;
00496 }
00497
00498 void Displayable::update_material(const Material *mat) {
00499 if (mat->ind == curr_material()) change_material(mat);
00500 for (int i=0; i<num_children; i++) children[i]->update_material(mat);
00501 }
00502
00503 void Displayable::delete_material(int n, const MaterialList *mlist) {
00504 if (n == curr_material()) {
00505 change_material(mlist->material(0));
00506 }
00507 for (int i=0; i<num_children; i++) children[i]->delete_material(n, mlist);
00508 }
00509
00510
00511
00512
00513
00514
00515 VMDDisplayList *Displayable::pick_cmd_list(void) {
00516 return cmdList;
00517 }
00518
00519
00520 int Displayable::pickable_on(void) {
00521 return displayed();
00522 }
00523
00524 void Displayable::color_changed(int cat) {
00525 do_color_changed(cat);
00526 for (int i=0; i<num_children; i++) child(i)->color_changed(cat);
00527 }
00528
00529 void Displayable::color_rgb_changed(int color) {
00530 do_color_rgb_changed(color);
00531 for (int i=0; i<num_children; i++) child(i)->color_rgb_changed(color);
00532 }
00533
00534 void Displayable::color_scale_changed() {
00535 do_color_scale_changed();
00536 for (int i=0; i<num_children; i++) child(i)->color_scale_changed();
00537 }
00538