lib/SmallChange/nodekits/SmAnnotationAxis.cpp

Tue Dec 13 15:35:52 2011 +0100

author
Tarjei Kvamme <tarjei.loset.kvamme@kongsberg.com>
date
Tue Dec 13 15:35:52 2011 +0100
changeset 1048
92bf2633a0df
parent 1011
239e70af5d84
permissions
-rw-r--r--

SIMRESERVOIR-3849: Use textMaterial to color the text when using an SmTextureText2Collector, as is done otherwise.

pederb@899 1 /**************************************************************************\
pederb@899 2 *
pederb@899 3 * This file is part of the SmallChange extension library for Coin.
pederb@899 4 * Copyright (C) 1998-2003 by Systems in Motion. All rights reserved.
pederb@899 5 *
pederb@899 6 * This library is free software; you can redistribute it and/or
pederb@899 7 * modify it under the terms of the GNU General Public License
pederb@899 8 * ("GPL") version 2 as published by the Free Software Foundation.
pederb@899 9 * See the file LICENSE.GPL at the root directory of this source
pederb@899 10 * distribution for additional information about the GNU GPL.
pederb@899 11 *
pederb@899 12 * For using SmallChange with software that can not be combined with the
pederb@899 13 * GNU GPL, and for taking advantage of the additional benefits of our
pederb@899 14 * support services, please contact Systems in Motion about acquiring
pederb@899 15 * a Coin Professional Edition License.
pederb@899 16 *
pederb@899 17 * See <URL:http://www.coin3d.org> for more information.
pederb@899 18 *
pederb@899 19 * Systems in Motion, Teknobyen, Abels Gate 5, 7030 Trondheim, NORWAY.
pederb@899 20 * <URL:http://www.sim.no>.
pederb@899 21 *
pederb@899 22 \**************************************************************************/
pederb@899 23
pederb@899 24 #include "SmAnnotationAxis.h"
pederb@899 25 #include <Inventor/nodes/SoSeparator.h>
pederb@899 26 #include <Inventor/elements/SoModelMatrixElement.h>
pederb@899 27 #include <Inventor/elements/SoProjectionMatrixElement.h>
pederb@899 28 #include <Inventor/elements/SoViewingMatrixElement.h>
pederb@899 29 #include <Inventor/elements/SoCacheElement.h>
pederb@899 30 #include <Inventor/elements/SoViewportRegionElement.h>
pederb@899 31 #include <Inventor/elements/SoViewVolumeElement.h>
pederb@899 32 #include <Inventor/elements/SoCullElement.h>
pederb@899 33 #include <Inventor/actions/SoGLRenderAction.h>
pederb@899 34 #include <Inventor/actions/SoGetBoundingBoxAction.h>
pederb@907 35 #include <Inventor/nodes/SoSwitch.h>
pederb@907 36 #include <Inventor/nodes/SoInfo.h>
pederb@907 37 #include <Inventor/nodes/SoMaterial.h>
pederb@907 38 #include <Inventor/nodes/SoLineSet.h>
pederb@907 39 #include <Inventor/nodes/SoSeparator.h>
pederb@907 40 #include <Inventor/nodes/SoVertexProperty.h>
pederb@929 41 #include <Inventor/SbTime.h>
pederb@929 42 #include <Inventor/sensors/SoAlarmSensor.h>
pederb@907 43 #include <Inventor/sensors/SoOneShotSensor.h>
pederb@899 44 #include <SmallChange/nodes/SmTextureText2.h>
pederb@977 45 #include <SmallChange/nodes/SmTextureText2Collector.h>
bfg@931 46 #include <cstring>
pederb@899 47
pederb@899 48 // *************************************************************************
pederb@899 49
pederb@899 50 SO_KIT_SOURCE(SmAnnotationAxis);
pederb@899 51
pederb@899 52 // *************************************************************************
pederb@899 53
pederb@899 54 class SmAnnotationAxisP {
pederb@899 55
pederb@899 56 public:
pederb@899 57 SmAnnotationAxisP(SmAnnotationAxis * master) {
pederb@899 58 this->master = master;
pederb@899 59 }
pederb@899 60
pederb@899 61 SmAnnotationAxis * master;
pederb@899 62 SbList <int> axisidx;
pederb@907 63 SoOneShotSensor * regen_sensor;
pederb@899 64
pederb@903 65 void add_anno_text(const int level,
pederb@903 66 SbList <int> & list,
pederb@899 67 const SbMatrix & projm,
pederb@967 68 const SbVec2s & vpsize,
pederb@967 69 const float gap,
pederb@899 70 const SbVec3f * pos, int i0, int i1);
pederb@929 71
pederb@929 72 SbTime lastchanged;
pederb@929 73 SoAlarmSensor * alarm;
pederb@929 74
pederb@929 75 static void alarmCB(void * closure, SoSensor * s) {
pederb@929 76 SmAnnotationAxisP * thisp = (SmAnnotationAxisP*) closure;
pederb@929 77 thisp->master->touch();
pederb@929 78 }
pederb@899 79 };
pederb@899 80
pederb@899 81 #define PRIVATE(p) ((p)->pimpl)
pederb@899 82 #define PUBLIC(p) ((p)->master)
pederb@899 83
pederb@899 84 // *************************************************************************
pederb@899 85
pederb@899 86 SmAnnotationAxis::SmAnnotationAxis()
pederb@899 87 {
pederb@899 88 PRIVATE(this) = new SmAnnotationAxisP(this);
pederb@907 89 PRIVATE(this)->regen_sensor = NULL;
pederb@929 90 PRIVATE(this)->alarm = new SoAlarmSensor(SmAnnotationAxisP::alarmCB, PRIVATE(this));
pederb@929 91 PRIVATE(this)->lastchanged = SbTime::zero();
pederb@899 92
pederb@899 93 SO_KIT_CONSTRUCTOR(SmAnnotationAxis);
pederb@899 94 SO_KIT_ADD_CATALOG_ENTRY(topSeparator, SoSeparator, FALSE, this, "", FALSE);
pederb@909 95 SO_KIT_ADD_CATALOG_ENTRY(textMaterial, SoMaterial, FALSE, topSeparator, text, TRUE);
pederb@908 96 SO_KIT_ADD_CATALOG_ENTRY(text, SmTextureText2, FALSE, topSeparator, axisSwitch, TRUE);
pederb@907 97 SO_KIT_ADD_CATALOG_ENTRY(axisSwitch, SoSwitch, FALSE, topSeparator, "", FALSE);
pederb@907 98 SO_KIT_ADD_CATALOG_ENTRY(noAxis, SoInfo, FALSE, axisSwitch, axisSep, FALSE);
pederb@907 99 SO_KIT_ADD_CATALOG_ENTRY(axisSep, SoSeparator, FALSE, axisSwitch, "", FALSE);
pederb@908 100 SO_KIT_ADD_CATALOG_ENTRY(axisMaterial, SoMaterial, FALSE, axisSep, axisLineSet, TRUE);
pederb@907 101 SO_KIT_ADD_CATALOG_ENTRY(axisLineSet, SoLineSet, FALSE, axisSep, "", FALSE);
pederb@907 102
pederb@899 103 SO_KIT_ADD_FIELD(annotation, (""));
pederb@899 104 SO_KIT_ADD_FIELD(annotationPos, (0.0f, 0.0f, 0.0f));
pederb@899 105 SO_KIT_ADD_FIELD(annotationGap, (30.0f));
pederb@907 106 SO_KIT_ADD_FIELD(renderAxis, (FALSE));
pederb@907 107 SO_KIT_ADD_FIELD(axisTickSize, (0.0f, 0.0f, 0.0f));
pederb@907 108 SO_KIT_ADD_FIELD(annotationOffset, (0.0f, 0.0f, 0.0f));
josteint@1011 109 SO_KIT_ADD_FIELD(annotationRot, (0.0f));
pederb@899 110
pederb@899 111 this->annotation.setNum(0);
pederb@899 112 this->annotationPos.setNum(0);
pederb@899 113 this->annotation.setDefault(TRUE);
pederb@899 114 this->annotationPos.setDefault(TRUE);
pederb@899 115
pederb@899 116 SO_KIT_INIT_INSTANCE();
pederb@907 117
rolvs@914 118 SoSwitch * sw = static_cast<SoSwitch*>(this->getAnyPart("axisSwitch", TRUE));
pederb@907 119 sw->whichChild.connectFrom(&this->renderAxis);
pederb@907 120
pederb@928 121 SmTextureText2 * t = static_cast<SmTextureText2*>(this->getAnyPart("text", TRUE));
pederb@928 122 t->justification = SmTextureText2::CENTER;
josteint@1011 123 t->rotation.connectFrom(&this->annotationRot);
pederb@928 124
pederb@907 125 PRIVATE(this)->regen_sensor = new SoOneShotSensor(regen_geometry, this);
pederb@899 126 }
pederb@899 127
pederb@899 128 SmAnnotationAxis::~SmAnnotationAxis()
pederb@899 129 {
pederb@929 130 delete PRIVATE(this)->alarm;
pederb@907 131 delete PRIVATE(this)->regen_sensor;
pederb@899 132 delete PRIVATE(this);
pederb@899 133 }
pederb@899 134
pederb@899 135 void
pederb@899 136 SmAnnotationAxis::initClass(void)
pederb@899 137 {
pederb@899 138 SO_KIT_INIT_CLASS(SmAnnotationAxis, SoBaseKit, "BaseKit");
pederb@899 139 }
pederb@899 140
pederb@899 141 void
pederb@899 142 SmAnnotationAxis::getBoundingBox(SoGetBoundingBoxAction * action)
pederb@899 143 {
pederb@899 144 SoState * state = action->getState();
pederb@899 145
pederb@978 146 // supply an approximate bbox and always invalidate the bbox cache
pederb@978 147 SoCacheElement::invalidate(state);
pederb@978 148
pederb@978 149 SbBox3f bbox;
pederb@978 150 bbox.makeEmpty();
pederb@978 151 for (int i = 0; i < this->annotationPos.getNum(); i++) {
pederb@978 152 bbox.extendBy(this->annotationPos[i]);
pederb@899 153 }
pederb@978 154
pederb@978 155 if (!bbox.isEmpty()) {
pederb@978 156 action->extendBy(bbox);
pederb@978 157 action->setCenter(bbox.getCenter(), TRUE);
pederb@899 158 }
pederb@978 159 inherited::getBoundingBox(action);
pederb@899 160 }
pederb@899 161
pederb@899 162 void
pederb@899 163 SmAnnotationAxis::GLRender(SoGLRenderAction * action)
pederb@899 164 {
pederb@899 165 SoState * state = action->getState();
pederb@899 166
pederb@899 167 SbBool render = TRUE;
pederb@978 168
pederb@956 169 // don't create render caches for this node
pederb@956 170 SoCacheElement::invalidate(state);
pederb@899 171
pederb@899 172 SbMatrix projmatrix;
pederb@899 173 projmatrix = (SoModelMatrixElement::get(state) *
pederb@899 174 SoViewingMatrixElement::get(state) *
pederb@899 175 SoProjectionMatrixElement::get(state));
pederb@899 176
pederb@899 177 SbVec2s vpsize = SoViewportRegionElement::get(state).getViewportSizePixels();
pederb@899 178 const SbViewVolume & vv = SoViewVolumeElement::get(state);
pederb@899 179 float maxsize = SbMax(vpsize[0], vpsize[1]);
pederb@899 180
pederb@899 181 SbList <int> l1;
pederb@899 182 if (this->annotationPos.getNum() >= 2) {
pederb@899 183 l1.truncate(0);
pederb@903 184 PRIVATE(this)->add_anno_text(0, l1, projmatrix,
pederb@967 185 vpsize,
pederb@967 186 this->annotationGap.getValue(),
pederb@899 187 this->annotationPos.getValues(0),
pederb@899 188 0, this->annotationPos.getNum() - 1);
pederb@899 189
pederb@899 190 }
pederb@977 191 if (SmTextureText2CollectorElement::isCollecting(state)) {
pederb@977 192 if (this->annotation.getNum()) {
tarjei@1048 193 SoMaterial * material = static_cast<SoMaterial*>(this->getAnyPart("textMaterial", TRUE));
tarjei@1048 194 SmTextureText2 * text = static_cast<SmTextureText2*>(this->getAnyPart("text", TRUE));
pederb@977 195 SbMatrix modelmatrix = SoModelMatrixElement::get(state);
pederb@977 196 SbVec3f pos;
tarjei@1048 197 SbColor4f col(material->diffuseColor[0], 1.0f - material->transparency[0]);
pederb@977 198
pederb@977 199 for (int i = 0; i < l1.getLength(); i++) {
pederb@977 200 pos = this->annotationPos[l1[i]] + this->annotationOffset.getValue();
pederb@977 201 modelmatrix.multVecMatrix(pos, pos);
pederb@977 202
pederb@977 203 SmTextureText2CollectorElement::add(state,
tarjei@1048 204 this->annotation.getValues(0)[l1[i] % this->annotation.getNum()],
pederb@977 205 SmTextureFontElement::get(state),
pederb@977 206 pos,
pederb@977 207 -1.0,
pederb@977 208 col,
tarjei@1048 209 static_cast<SmTextureText2::Justification>(text->justification.getValue()),
tarjei@1048 210 static_cast<SmTextureText2::VerticalJustification>(text->verticalJustification.getValue()));
pederb@977 211
tarjei@1048 212 if (text->string.getNum()) text->string.setNum(0);
pederb@929 213 }
pederb@929 214 }
pederb@977 215 }
pederb@977 216 else {
pederb@977 217 if (l1 != PRIVATE(this)->axisidx) {
pederb@977 218 // avoid that we update the scene graph and trigger redraws too often
pederb@977 219 SbTime curtime = SbTime::getTimeOfDay();
pederb@977 220 if ((curtime.getValue() - PRIVATE(this)->lastchanged.getValue()) < 0.5) {
pederb@977 221 if (!PRIVATE(this)->alarm->isScheduled()) {
pederb@977 222 PRIVATE(this)->alarm->setTimeFromNow(1.0);
pederb@977 223 PRIVATE(this)->alarm->schedule();
pederb@977 224 }
pederb@929 225 }
pederb@977 226 else {
pederb@977 227 PRIVATE(this)->lastchanged = curtime;
pederb@977 228 SmTextureText2 * t = static_cast<SmTextureText2*>(this->getAnyPart("text", TRUE));
pederb@977 229 assert(t);
pederb@977 230 t->position.setNum(l1.getLength());
pederb@977 231 t->string.setNum(l1.getLength());
pederb@977 232 SbVec3f * pos = t->position.startEditing();
pederb@977 233 SbString * text = t->string.startEditing();
pederb@977 234 for (int i = 0; i < l1.getLength(); i++) {
pederb@977 235 pos[i] = this->annotationPos[l1[i]] + this->annotationOffset.getValue();
pederb@977 236 text[i] = this->annotation.getNum() > 0 ?
pederb@977 237 this->annotation.getValues(0)[l1[i]%this->annotation.getNum()] : "";
pederb@977 238 }
pederb@977 239 t->position.finishEditing();
pederb@977 240 t->string.finishEditing();
pederb@977 241
pederb@977 242 PRIVATE(this)->axisidx = l1;
pederb@977 243 }
pederb@899 244 }
pederb@899 245 }
pederb@899 246 if (render) inherited::GLRender(action);
pederb@899 247 }
pederb@899 248
pederb@899 249 void
pederb@899 250 SmAnnotationAxis::notify(SoNotList * list)
pederb@899 251 {
pederb@907 252 if (PRIVATE(this)->regen_sensor) {
pederb@907 253 SoField * f = list->getLastField();
pederb@907 254 if ((f == &this->annotationPos) ||
pederb@907 255 (f == &this->renderAxis) ||
pederb@907 256 (f == &this->axisTickSize)) {
pederb@907 257 PRIVATE(this)->regen_sensor->schedule();
pederb@907 258 }
pederb@907 259 }
pederb@899 260 inherited::notify(list);
pederb@899 261 }
pederb@899 262
pederb@907 263 void
pederb@907 264 SmAnnotationAxis::regen_geometry(void * userdata, SoSensor * s)
pederb@907 265 {
pederb@907 266 SmAnnotationAxis * thisp = (SmAnnotationAxis*) userdata;
pederb@907 267 if (thisp->renderAxis.getValue()) {
rolvs@914 268 SoLineSet * ls = static_cast<SoLineSet*>(thisp->getAnyPart("axisLineSet", TRUE));
rolvs@914 269 SoVertexProperty * vp = static_cast<SoVertexProperty*> (ls->vertexProperty.getValue());
pederb@907 270 if (vp == NULL) {
pederb@907 271 vp = new SoVertexProperty;
pederb@907 272 ls->vertexProperty = vp;
pederb@907 273 }
pederb@907 274 SbVec3f ticksize = thisp->axisTickSize.getValue();
pederb@907 275
pederb@907 276 const int numanno = thisp->annotationPos.getNum();
pederb@907 277 const int numlines = 1 + ((ticksize.length() > 0.0f) ? numanno : 0);
pederb@907 278 const int numcoords = numanno + ((ticksize.length() > 0.0f) ? numanno*2 : 0);
pederb@907 279
pederb@907 280 vp->vertex.setNum(numcoords);
pederb@907 281 ls->numVertices.setNum(numlines);
pederb@907 282
pederb@907 283 const SbVec3f * src = thisp->annotationPos.getValues(0);
pederb@907 284 SbVec3f * pts = vp->vertex.startEditing();
pederb@907 285 int32_t * v = ls->numVertices.startEditing();
pederb@907 286
pederb@907 287 v[0] = numanno;
pederb@907 288
pederb@907 289 int i;
pederb@907 290
pederb@907 291 for (i = 0; i < numanno; i++) {
pederb@907 292 pts[i] = thisp->annotationPos[i];
pederb@907 293 }
pederb@907 294 if (ticksize.length() > 0.0f) {
pederb@907 295 for (i = 0; i < numanno; i++) {
pederb@907 296 v[i+1] = 2;
pederb@907 297 pts[i*2+numanno] = src[i];
pederb@907 298 pts[i*2+1+numanno] = src[i] + ticksize;
pederb@907 299 }
pederb@907 300 }
pederb@907 301
pederb@907 302 vp->vertex.finishEditing();
pederb@907 303 ls->numVertices.finishEditing();
pederb@907 304 }
pederb@907 305 }
pederb@907 306
pederb@899 307 // *************************************************************************
pederb@899 308
pederb@899 309 void
pederb@903 310 SmAnnotationAxisP::add_anno_text(const int level,
pederb@903 311 SbList <int> & list,
pederb@899 312 const SbMatrix & projm,
pederb@967 313 const SbVec2s & vpsize,
pederb@967 314 const float gap,
pederb@899 315 const SbVec3f * pos, int i0, int i1)
pederb@899 316 {
pederb@905 317 if (i0 == i1) return;
pederb@905 318
pederb@899 319 int mid = (i0 + i1) / 2;
pederb@899 320 SbVec3f p[3];
pederb@899 321 p[0] = pos[i0];
pederb@899 322 p[1] = pos[mid];
pederb@899 323 p[2] = pos[i1];
pederb@899 324
pederb@899 325 int i;
pederb@899 326 for (i = 0; i < 3; i++) {
pederb@899 327 projm.multVecMatrix(p[i], p[i]);
pederb@899 328 }
pederb@905 329
pederb@903 330 if (level == 0) { // special case to handle the corner points
pederb@903 331 if ((p[0][2] < 1.0f) && (p[2][2] < 1.0f)) {
pederb@903 332 SbVec3f d = p[2]-p[0];
pederb@967 333 d[0] = SbAbs(d[0]) * float(vpsize[0]) * 0.5f;
pederb@967 334 d[1] = SbAbs(d[1]) * float(vpsize[1]) * 0.5f;
pederb@903 335 d[2] = 0.0f;
pederb@967 336
pederb@903 337 float len = d.length();
pederb@967 338 if (len > gap) {
pederb@903 339 list.append(i0);
pederb@903 340 list.append(i1);
pederb@903 341 }
pederb@903 342 }
pederb@903 343 else if (p[0][2] < 1.0f) {
pederb@903 344 list.append(i0);
pederb@903 345 }
pederb@903 346 else if (p[2][2] < 1.0f) {
pederb@903 347 list.append(i1);
pederb@903 348 }
pederb@903 349 }
pederb@905 350
pederb@905 351 if ((mid == i0) || (mid == i1)) return;
pederb@905 352
pederb@900 353 if (p[1][2] < 1.0f) {
pederb@899 354 SbBool add = FALSE;
pederb@899 355 float len = 0.0f;
pederb@900 356 if (p[0][2] < 1.0f) {
pederb@967 357 SbVec3f d = p[1]-p[0];
pederb@967 358 d[0] = SbAbs(d[0]) * float(vpsize[0]) * 0.5f;
pederb@967 359 d[1] = SbAbs(d[1]) * float(vpsize[1]) * 0.5f;
pederb@967 360 d[2] = 0.0f;
pederb@967 361
pederb@967 362 len = d.length();
pederb@899 363 }
pederb@900 364 else if (p[2][2] < 1.0f) {
pederb@967 365 SbVec3f d = p[1]-p[2];
pederb@967 366 d[0] = SbAbs(d[0]) * float(vpsize[0]) * 0.5f;
pederb@967 367 d[1] = SbAbs(d[1]) * float(vpsize[1]) * 0.5f;
pederb@967 368 d[2] = 0.0f;
pederb@967 369 len = d.length();
pederb@899 370 }
pederb@967 371 if (len > gap) {
pederb@899 372 list.append(mid);
pederb@899 373 }
pederb@899 374 }
pederb@967 375 add_anno_text(level+1, list, projm, vpsize, gap, pos, i0, mid);
pederb@967 376 add_anno_text(level+1, list, projm, vpsize, gap, pos, mid, i1);
pederb@899 377 }
pederb@899 378
pederb@899 379 // *************************************************************************

Kongsberg Oil & Gas Technologies repositories