1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 /*!
34   \class RGBCubeEditorKit RGBCubeEditorKit.h
35   \brief The RGBCubeEditorKit class is an editor for setting a RGB triplet color value.
36 
37   This is a 3D user interface component.
38 
39   Example usage:
40 
41   \code
42   #include <Inventor/Qt/SoQt.h>
43   #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
44   #include <Inventor/nodes/SoSeparator.h>
45   #include "RGBCubeEditorKit.h"
46 
47   static void myRgbChangeCallback(void * userData, SoSensor * sensor)
48   {
49     SoFieldSensor * fieldSensor = (SoFieldSensor *) sensor;
50     SoMFColor * color = (SoMFColor *) fieldSensor->getAttachedField();
51   }
52 
53   int
54   main(int argc, char ** argv)
55   {
56     QWidget * mainwin = SoQt::init(argc, argv, argv[0]);
57     RGBCubeEditorKit::initClass();
58 
59     SoSeparator * root = new SoSeparator;
60     root->ref();
61 
62     // Creating the cube object
63     RGBCubeEditorKit *rgbCube = new RGBCubeEditorKit;
64     root->addChild(rgbCube);
65 
66     // Attaching a sensor to the 'rgb' field in the RGBCubeEditorKit
67     SoFieldSensor * rgbCubeSensor = new SoFieldSensor(myRgbChangeCallback,this);
68     rgbCubeSensor->attach(&rgbCube->rgb);
69 
70     // Setup scene
71     SoQtExaminerViewer * viewer = new SoQtExaminerViewer(mainwin);
72     viewer->setSceneGraph(root);
73     viewer->show();
74 
75     SoQt::show(mainwin);
76     SoQt::mainLoop();
77 
78     delete viewer;
79     root->unref();
80 
81     return 0;
82   }
83   \endcode
84 */
85 
86 #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
87 #include <Inventor/SoPickedPoint.h>
88 
89 #include <Inventor/nodes/SoCube.h>
90 #include <Inventor/draggers/SoScale1Dragger.h>
91 #include <Inventor/nodes/SoTranslation.h>
92 #include <Inventor/nodes/SoSeparator.h>
93 #include <Inventor/nodes/SoRotation.h>
94 #include <Inventor/nodes/SoMaterial.h>
95 #include <Inventor/nodes/SoText2.h>
96 #include <Inventor/nodes/SoFont.h>
97 #include <Inventor/nodes/SoBaseColor.h>
98 #include <Inventor/nodes/SoFaceSet.h>
99 #include <Inventor/nodes/SoCoordinate3.h>
100 #include <Inventor/nodes/SoMaterialBinding.h>
101 #include <Inventor/nodes/SoLightModel.h>
102 #include <Inventor/nodes/SoLight.h>
103 #include <Inventor/nodes/SoIndexedFaceSet.h>
104 #include <Inventor/nodes/SoVertexProperty.h>
105 #include <Inventor/nodes/SoIndexedLineSet.h>
106 #include <Inventor/nodes/SoSphere.h>
107 #include <Inventor/nodes/SoTransformSeparator.h>
108 #include <Inventor/nodes/SoSelection.h>
109 #include <Inventor/nodes/SoShapeHints.h>
110 #include <Inventor/nodes/SoEventCallback.h>
111 #include <Inventor/events/SoMouseButtonEvent.h>
112 #include <Inventor/actions/SoRayPickAction.h>
113 #include <Inventor/nodes/SoMarkerSet.h>
114 #include <Inventor/nodes/SoCylinder.h>
115 #include <Inventor/nodes/SoRotationXYZ.h>
116 #include <Inventor/nodes/SoAntiSquish.h>
117 #include <Inventor/nodes/SoTransformation.h>
118 #include <Inventor/nodes/SoPickStyle.h>
119 #include <Inventor/actions/SoGetMatrixAction.h>
120 
121 #include "RGBCubeEditorKit.h"
122 
123 // *************************************************************************
124 
125 SO_KIT_SOURCE(RGBCubeEditorKit);
126 
127 // *************************************************************************
128 
129 static const int CUBE_SIZE_X = 2;
130 static const int CUBE_SIZE_Y = 2;
131 static const int CUBE_SIZE_Z = 2;
132 
133 class RGBCubeEditorKitP {
134 public:
RGBCubeEditorKitP(RGBCubeEditorKit * master)135   RGBCubeEditorKitP(RGBCubeEditorKit * master) {
136     this->master = master;
137   }
138 
139   float draggerXValue;
140   float draggerYValue;
141   float draggerZValue;
142   SoScale1Dragger * draggerX;             // RGB draggers
143   SoScale1Dragger * draggerY;
144   SoScale1Dragger * draggerZ;
145   SoMaterial * cubeMaterial;              // Rgb cube material
146   SoCoordinate3 * colorCubeCoords;
147   SoIndexedFaceSet * cubeIndexedFacelist;
148   SoTransformSeparator * cubeRoot;
149   SoText2 * textRedValue;                 // Text on axis
150   SoText2 * textGreenValue;
151   SoText2 * textBlueValue;
152   SoTranslation * colorIndicatorPosition; // Current color indicator 'o'
153   SbVec3f * cubeVertices;
154   SoFieldSensor * rgbSensor;
155 
156   void draggerCallback(void);
157 
158   void initRgbCube(void);
159 
160   void initCubeFacelist(SoTransformSeparator * root,
161                      SoCoordinate3 * colorCubeCoords,
162                      SoMaterial * cubeMaterial);
163 
164   void initCubeDraggers(SoSeparator * root,
165                      SoScale1Dragger * draggerX,
166                      SoScale1Dragger * draggerY,
167                      SoScale1Dragger * draggerZ,
168                      SoDraggerCB * cb1,
169                      SoDraggerCB * cb2,
170                      SoDraggerCB * cb3,
171                      float value1, float value2, float value3);
172 
173   void updateCubeVertices(SoCoordinate3 * colorCubeCoords,
174                        SoMaterial * cubeMaterial,
175                        float x, float y, float z);
176 
177   void modifyDraggerWidget(SoScale1Dragger * dragger);
178 
179   void updateColorValueText(float red, float green, float blue);
180 
181   static void rgbChangedCallback(void * classObject, SoSensor * sensor);
182   static void mouseClickCallback(void *classObject, SoEventCallback * cb);
183   static void draggerXCallback(void * classObject, SoDragger * dragger);
184   static void draggerYCallback(void * classObject, SoDragger * dragger);
185   static void draggerZCallback(void * classObject, SoDragger * dragger);
186 
187 
188 
189 private:
190   RGBCubeEditorKit * master;
191 };
192 
193 #define PRIVATE(p) (p->pimpl)
194 #define PUBLIC(p) (p->master)
195 
196 // *************************************************************************
197 
RGBCubeEditorKit(void)198 RGBCubeEditorKit::RGBCubeEditorKit(void)
199 {
200 
201   PRIVATE(this) = new RGBCubeEditorKitP(this);
202 
203   SO_KIT_CONSTRUCTOR(RGBCubeEditorKit);
204   SO_KIT_ADD_CATALOG_ENTRY(RGBCubeRoot, SoSeparator, TRUE, this, "", TRUE);
205 
206   SO_KIT_ADD_FIELD(rgb, (SbColor(0.8, 0.8, 0.8)));
207   SO_KIT_INIT_INSTANCE();
208 
209   PRIVATE(this)->draggerXValue = 0.8;
210   PRIVATE(this)->draggerYValue = 0.8;
211   PRIVATE(this)->draggerZValue = 0.8;
212 
213   PRIVATE(this)->initRgbCube();
214 
215   PRIVATE(this)->rgbSensor = new SoFieldSensor(pimpl->rgbChangedCallback,PRIVATE(this));
216   PRIVATE(this)->rgbSensor->setPriority(0);
217   PRIVATE(this)->rgbSensor->attach(&this->rgb);
218 
219 }
220 
~RGBCubeEditorKit()221 RGBCubeEditorKit::~RGBCubeEditorKit()
222 {
223   delete PRIVATE(this)->rgbSensor;
224   delete PRIVATE(this);
225 }
226 
227 void
initClass(void)228 RGBCubeEditorKit::initClass(void)
229 {
230   SO_KIT_INIT_CLASS(RGBCubeEditorKit, SoInteractionKit, "InteractionKit");
231 }
232 
233 SbBool
affectsState(void) const234 RGBCubeEditorKit::affectsState(void) const
235 {
236   return FALSE;
237 }
238 
239 void
rgbChangedCallback(void * classObject,SoSensor * sensor)240 RGBCubeEditorKitP::rgbChangedCallback(void * classObject, SoSensor * sensor)
241 {
242 
243   RGBCubeEditorKitP * rgbCubeP = (RGBCubeEditorKitP *) classObject;  // Fetch caller object
244 
245   rgbCubeP->draggerXValue = rgbCubeP->master->rgb[0][0];
246   rgbCubeP->draggerYValue = rgbCubeP->master->rgb[0][1];
247   rgbCubeP->draggerZValue = rgbCubeP->master->rgb[0][2];
248 
249   rgbCubeP->draggerX->scaleFactor.setValue(rgbCubeP->draggerXValue,1,1);
250   rgbCubeP->draggerY->scaleFactor.setValue(rgbCubeP->draggerYValue,1,1);
251   rgbCubeP->draggerZ->scaleFactor.setValue(rgbCubeP->draggerZValue,1,1);
252 
253   // Detach sensor to prevent inf. loop. before changing 'rgb' field
254   SoFieldSensor * rgbSensor = (SoFieldSensor *) sensor;
255   rgbSensor->detach();
256   rgbCubeP->draggerCallback();
257   rgbSensor->attach(&rgbCubeP->master->rgb);
258 
259 }
260 
261 void
mouseClickCallback(void * classObject,SoEventCallback * cb)262 RGBCubeEditorKitP::mouseClickCallback(void * classObject, SoEventCallback * cb)
263 {
264 
265   SoMouseButtonEvent * mouseEvent = (SoMouseButtonEvent *) (cb->getEvent());
266 
267   if(mouseEvent->getButton() == SoMouseButtonEvent::BUTTON1 &&
268      mouseEvent->getState() == SoButtonEvent::UP) return;
269 
270   RGBCubeEditorKitP * rgbCubeP = (RGBCubeEditorKitP *) classObject;  // Fetch caller object
271 
272   // Fetch viewport and scenegraph
273   SoHandleEventAction * handleaction = cb->getAction();
274   const SbViewportRegion viewport = handleaction->getViewportRegion();
275   const SoPath * scenePath = handleaction->getCurPath();
276   SoNode * sceneRoot = scenePath->getHead();
277 
278 
279   // Fetch translation of this cube
280   SoPath * scenePathCopy = scenePath->copy();
281   scenePathCopy->ref();
282   SoGetMatrixAction matrixAction(viewport);
283   matrixAction.apply(scenePathCopy);
284   SbMatrix matrix = matrixAction.getMatrix();
285   scenePathCopy->unref();
286 
287   SbVec3f scale, translation;
288   SbRotation rotation, scaleo;
289   matrix.getTransform(translation, rotation, scale, scaleo);
290 
291   SoRayPickAction rayPickAction(viewport);
292   SbVec2s pos(mouseEvent->getPosition());
293   rayPickAction.setPoint(mouseEvent->getPosition());
294   rayPickAction.apply(sceneRoot);
295 
296 
297   SoPickedPoint * myPP = rayPickAction.getPickedPoint();
298   if(myPP == NULL)
299     return;  // no object were selected. aborting.
300 
301 
302   SoFullPath * path = (SoFullPath *)myPP->getPath();
303   SoNode * end = path->getTail();
304 
305 
306   if(end == rgbCubeP->cubeIndexedFacelist){  // Is this the IndexedFaceSet object?
307 
308     SbVec3f ipoint = myPP->getPoint();
309 
310     SbVec3f cubeOrigo = rgbCubeP->colorCubeCoords->point[0];
311     cubeOrigo[0] += translation[0];
312     cubeOrigo[1] += translation[1];
313     cubeOrigo[2] += translation[2];
314 
315     // Find new corner for color cube.
316     SbVec3f newPoint;
317     newPoint[0] = (ipoint[0] - cubeOrigo[0])/CUBE_SIZE_X;
318     newPoint[1] = (ipoint[1] - cubeOrigo[1])/CUBE_SIZE_Y;
319     newPoint[2] = (ipoint[2] - cubeOrigo[2])/CUBE_SIZE_Z;
320 
321     // Chech if new corner is out of bounds
322     if(newPoint[0] > CUBE_SIZE_X/2) newPoint[0] = CUBE_SIZE_X/2;
323     if(newPoint[1] > CUBE_SIZE_Y/2) newPoint[1] = CUBE_SIZE_Y/2;
324     if(newPoint[2] > CUBE_SIZE_Z/2) newPoint[2] = CUBE_SIZE_Z/2;
325 
326     rgbCubeP->draggerX->scaleFactor.setValue(newPoint[0], 1, 1);
327     rgbCubeP->draggerY->scaleFactor.setValue(newPoint[1], 1, 1);
328     rgbCubeP->draggerZ->scaleFactor.setValue(newPoint[2], 1, 1);
329     rgbCubeP->draggerXValue = newPoint[0];
330     rgbCubeP->draggerYValue = newPoint[1];
331     rgbCubeP->draggerZValue = newPoint[2];
332     rgbCubeP->draggerCallback();
333 
334   }
335 }
336 
337 
338 void
updateColorValueText(float red,float green,float blue)339 RGBCubeEditorKitP::updateColorValueText(float red, float green, float blue)
340 {
341 
342   if(red < 0) red = 0;
343   if(green < 0) green = 0;
344   if(blue < 0) blue = 0;
345 
346   char buffer[8];
347 
348   sprintf(buffer, "[%.2f]", red);
349   this->textRedValue->string = buffer;
350 
351   sprintf(buffer, "[%.2f]", green);
352   this->textGreenValue->string = buffer;
353 
354   sprintf(buffer, "[%.2f]", blue);
355   this->textBlueValue->string = buffer;
356 
357 }
358 
359 
360 void
draggerCallback(void)361 RGBCubeEditorKitP::draggerCallback(void)
362 {
363   this->updateCubeVertices(this->colorCubeCoords,
364                            this->cubeMaterial,
365                            draggerXValue,
366                            draggerYValue,
367                            draggerZValue);
368   this->updateColorValueText(draggerXValue, draggerYValue, draggerZValue);
369 
370   // Update global RGB field
371   PUBLIC(this)->rgb.setValue(draggerXValue, draggerYValue, draggerZValue);
372 }
373 
374 
375 void
draggerXCallback(void * obj,SoDragger * dragger)376 RGBCubeEditorKitP::draggerXCallback(void * obj, SoDragger * dragger)
377 {
378   RGBCubeEditorKit * rgbCube = (RGBCubeEditorKit *)obj;
379   SoScale1Dragger * sd = (SoScale1Dragger *)dragger;
380   PRIVATE(rgbCube)->draggerXValue = sd->scaleFactor.getValue()[0];
381   if(PRIVATE(rgbCube)->draggerXValue > 1.0)
382     PRIVATE(rgbCube)->draggerXValue = 1;
383   if(PRIVATE(rgbCube)->draggerXValue < 0.0001)
384     PRIVATE(rgbCube)->draggerXValue = 0.0001;
385   PRIVATE(rgbCube)->draggerCallback();
386 }
387 
388 
389 void
draggerYCallback(void * obj,SoDragger * dragger)390 RGBCubeEditorKitP::draggerYCallback(void * obj, SoDragger * dragger)
391 {
392   RGBCubeEditorKit * rgbCube = (RGBCubeEditorKit *)obj;
393   SoScale1Dragger * sd = (SoScale1Dragger *)dragger;
394   PRIVATE(rgbCube)->draggerYValue = sd->scaleFactor.getValue()[0];
395   if(PRIVATE(rgbCube)->draggerYValue > 1.0)
396     PRIVATE(rgbCube)->draggerYValue = 1;
397   if(PRIVATE(rgbCube)->draggerYValue < 0.0001)
398     PRIVATE(rgbCube)->draggerYValue = 0.0001;
399   PRIVATE(rgbCube)->draggerCallback();
400 }
401 
402 
403 void
draggerZCallback(void * obj,SoDragger * dragger)404 RGBCubeEditorKitP::draggerZCallback(void * obj, SoDragger * dragger)
405 {
406   RGBCubeEditorKit * rgbCube = (RGBCubeEditorKit *)obj;
407   SoScale1Dragger * sd = (SoScale1Dragger *)dragger;
408   PRIVATE(rgbCube)->draggerZValue = sd->scaleFactor.getValue()[0];
409   if(PRIVATE(rgbCube)->draggerZValue > 1.0)
410     PRIVATE(rgbCube)->draggerZValue = 1;
411   if(PRIVATE(rgbCube)->draggerZValue < 0.0001)
412     PRIVATE(rgbCube)->draggerZValue = 0.0001;
413   PRIVATE(rgbCube)->draggerCallback();
414 }
415 
416 
417 void
updateCubeVertices(SoCoordinate3 * cubeCoords,SoMaterial * cubeMaterial,float x,float y,float z)418 RGBCubeEditorKitP::updateCubeVertices(SoCoordinate3 * cubeCoords,
419                               SoMaterial * cubeMaterial,
420                               float x, float y, float z)
421 {
422 
423   // X-face
424   cubeCoords->point.set1Value(6, x*CUBE_SIZE_X, y*CUBE_SIZE_Y, z*CUBE_SIZE_Z);
425   cubeCoords->point.set1Value(2, x*CUBE_SIZE_X, y*CUBE_SIZE_Y, 0);
426   cubeCoords->point.set1Value(1, x*CUBE_SIZE_X, 0, 0);
427   cubeCoords->point.set1Value(5, x*CUBE_SIZE_X, 0, z*CUBE_SIZE_Z);
428 
429   // Y-face
430   cubeCoords->point.set1Value(3, 0, y*CUBE_SIZE_Y, 0);
431   cubeCoords->point.set1Value(7, 0, y*CUBE_SIZE_Y, z*CUBE_SIZE_Z);
432 
433   // Z-face
434   cubeCoords->point.set1Value(7, 0, y*CUBE_SIZE_Y, z*CUBE_SIZE_Z);
435   cubeCoords->point.set1Value(4, 0, 0, z*CUBE_SIZE_Z);
436 
437   cubeMaterial->diffuseColor.set1Value(1, x, 0, 0);
438   cubeMaterial->diffuseColor.set1Value(2, x, y, 0);
439   cubeMaterial->diffuseColor.set1Value(3, 0, y, 0);
440   cubeMaterial->diffuseColor.set1Value(4, 0, 0, z);
441   cubeMaterial->diffuseColor.set1Value(5, x, 0, z);
442   cubeMaterial->diffuseColor.set1Value(6, x, y, z);
443   cubeMaterial->diffuseColor.set1Value(7, 0, y, z);
444 
445   colorIndicatorPosition->translation.setValue(cubeCoords->point[6]);
446 
447 }
448 
449 
450 void
initCubeFacelist(SoTransformSeparator * root,SoCoordinate3 * cubeCoords,SoMaterial * cubeMaterial)451 RGBCubeEditorKitP::initCubeFacelist(SoTransformSeparator * root,
452                             SoCoordinate3 * cubeCoords,
453                             SoMaterial * cubeMaterial)
454 {
455 
456   SbVec3f cubeVerts[4*2];
457   int32_t cubeVertexIndices[] = {3,2,1,0, SO_END_FACE_INDEX,
458                              5,6,7,4, SO_END_FACE_INDEX,
459                              4,7,3,0, SO_END_FACE_INDEX,
460                              5,1,2,6, SO_END_FACE_INDEX,
461                              7,6,2,3, SO_END_FACE_INDEX,
462                              5,4,0,1, SO_END_FACE_INDEX };
463 
464   // Back
465   cubeVerts[0].setValue(0, 0, 0);
466   cubeVerts[1].setValue(CUBE_SIZE_X, 0, 0);
467   cubeVerts[2].setValue(CUBE_SIZE_X, CUBE_SIZE_Y, 0);
468   cubeVerts[3].setValue(0, CUBE_SIZE_Y, 0);
469 
470   // Front
471   cubeVerts[4].setValue(0, 0, CUBE_SIZE_Z);
472   cubeVerts[5].setValue(CUBE_SIZE_X, 0, CUBE_SIZE_Z);
473   cubeVerts[6].setValue(CUBE_SIZE_X, CUBE_SIZE_Y, CUBE_SIZE_Z);
474   cubeVerts[7].setValue(0, CUBE_SIZE_Y, CUBE_SIZE_Z);
475 
476 
477   // Vertex colors
478   cubeMaterial->diffuseColor.set1Value(0, 0,0,0);
479   cubeMaterial->diffuseColor.set1Value(1, 1,0,0);
480   cubeMaterial->diffuseColor.set1Value(2, 1,1,0);
481   cubeMaterial->diffuseColor.set1Value(3, 0,1,0);
482 
483   cubeMaterial->diffuseColor.set1Value(4, 0,0,1);
484   cubeMaterial->diffuseColor.set1Value(5, 1,0,1);
485   cubeMaterial->diffuseColor.set1Value(6, 1,1,1);
486   cubeMaterial->diffuseColor.set1Value(7, 0,1,1);
487 
488 
489   // ColorCube + LineCube coordinates
490   SoCoordinate3 * lineCubeCoords = new SoCoordinate3;
491   lineCubeCoords->point.setValues(0,4*2,cubeVerts);
492   cubeCoords->point.setValues(0,4*2,cubeVerts);
493 
494 
495   // Cube faceset
496   cubeIndexedFacelist = new SoIndexedFaceSet;
497   cubeIndexedFacelist->coordIndex.setValues(0, 6*5, cubeVertexIndices);
498 
499 
500   // Cube lineset
501   SoIndexedLineSet * cubeLineList = new SoIndexedLineSet;
502   cubeLineList->coordIndex.setValues(0, 6*5, cubeVertexIndices);
503   SoMaterial * cubeLineMaterial = new SoMaterial;
504   cubeLineMaterial->diffuseColor.set1Value(0,1,1,1);
505 
506 
507   // Cube material
508   SoMaterialBinding * cubeMatBind = new SoMaterialBinding;
509   cubeMatBind->value = SoMaterialBinding::PER_VERTEX_INDEXED;
510 
511 
512   // No lighting of color-cube
513   SoLightModel * cubeLight = new SoLightModel;
514   cubeLight->model = SoLightModel::BASE_COLOR;
515 
516 
517   // Current color indicator
518   SoSeparator * colorIndicatorRoot = new SoSeparator;
519 
520   SoMarkerSet * colorIndicator = new SoMarkerSet;
521   colorIndicator->markerIndex = SoMarkerSet::CIRCLE_LINE_9_9;
522   colorIndicator->numPoints = 1;
523 
524   SoBaseColor * colorIndicatorColor = new SoBaseColor;
525   colorIndicatorColor->rgb.setValue(1,0,0);
526   colorIndicatorRoot = new SoSeparator;
527   colorIndicatorPosition->translation.setValue(cubeVerts[6].getValue());
528 
529   colorIndicatorRoot->addChild(colorIndicatorPosition);
530   colorIndicatorRoot->addChild(colorIndicatorColor);
531   colorIndicatorRoot->addChild(colorIndicator);
532 
533 
534   // build scenegraph
535   root->addChild(cubeMatBind);
536   root->addChild(cubeMaterial);
537   root->addChild(cubeLight);
538   root->addChild(cubeCoords);
539   root->addChild(cubeIndexedFacelist);
540 
541   SoPickStyle * pickStyle = new SoPickStyle;
542   pickStyle->style = SoPickStyle::UNPICKABLE;
543 
544   SoSeparator * lineRoot = new SoSeparator;
545   lineRoot->addChild(pickStyle);              // Make the linecube unpickable
546   lineRoot->addChild(lineCubeCoords);
547   lineRoot->addChild(cubeLineMaterial);
548   lineRoot->addChild(cubeLineList);
549   root->addChild(lineRoot);
550 
551   root->addChild(colorIndicatorRoot);
552 
553 }
554 
555 
556 void
initCubeDraggers(SoSeparator * root,SoScale1Dragger * draggerX,SoScale1Dragger * draggerY,SoScale1Dragger * draggerZ,SoDraggerCB * cb1,SoDraggerCB * cb2,SoDraggerCB * cb3,float value1,float value2,float value3)557 RGBCubeEditorKitP::initCubeDraggers(SoSeparator * root,
558                                SoScale1Dragger * draggerX,
559                                SoScale1Dragger * draggerY,
560                                SoScale1Dragger * draggerZ,
561                                SoDraggerCB * cb1,
562                                SoDraggerCB * cb2,
563                                SoDraggerCB * cb3,
564                                float value1,float value2, float value3)
565 {
566 
567   draggerX->scaleFactor.setValue(value1,1,1);
568   draggerY->scaleFactor.setValue(value2,1,1);
569   draggerZ->scaleFactor.setValue(value3,1,1);
570 
571   draggerX->addMotionCallback(cb1, PUBLIC(this));
572   draggerY->addMotionCallback(cb2, PUBLIC(this));
573   draggerZ->addMotionCallback(cb3, PUBLIC(this));
574 
575 
576   SoTranslation * draggerXTrans = new SoTranslation;
577   SoTranslation * draggerYTrans = new SoTranslation;
578   SoTranslation * draggerZTrans = new SoTranslation;
579 
580   SoSeparator * sep = new SoSeparator;
581 
582   SoRotation * draggerXRotation = new SoRotation;
583   SoRotation * draggerYRotation = new SoRotation;
584   SoRotation * draggerZRotation = new SoRotation;
585 
586   draggerXRotation->rotation.setValue(0,1,1,0);
587   draggerYRotation->rotation.setValue(1,0,1,0);
588   draggerZRotation->rotation.setValue(1,1,0,0);
589 
590   draggerXTrans->translation.setValue( CUBE_SIZE_X/2, 0, CUBE_SIZE_Z+.2);
591   draggerYTrans->translation.setValue(-CUBE_SIZE_X/2-.2, -CUBE_SIZE_Y-.2, CUBE_SIZE_Z/2+.1);
592   draggerZTrans->translation.setValue(-CUBE_SIZE_X/2-.2, -CUBE_SIZE_Y/2-.2, 0);
593 
594 
595   // Axis - Text
596   SoFont * font = new SoFont;
597   font->name.setValue("Times-Roman");
598   font->size.setValue(24.0);
599   root->addChild(font);
600 
601   SoPickStyle * pickStyle = new SoPickStyle;
602   pickStyle->style = SoPickStyle::UNPICKABLE;
603 
604   SoTranslation * textTrans = new SoTranslation;
605   textTrans->translation.setValue(0,.3,-.2);
606 
607   SoSeparator * textRedSep = new SoSeparator;
608   SoSeparator * textGreenSep = new SoSeparator;
609   SoSeparator * textBlueSep = new SoSeparator;
610 
611   SoBaseColor * textRedColor = new SoBaseColor;
612   textRedColor->rgb.setValue(1,.4,.4);
613   SoBaseColor * textGreenColor = new SoBaseColor;
614   textGreenColor->rgb.setValue(.4,1,.4);
615   SoBaseColor * textBlueColor = new SoBaseColor;
616   textBlueColor->rgb.setValue(.4,.4,1);
617 
618   textRedSep->addChild(pickStyle);
619   textRedSep->addChild(textRedColor);
620   textRedSep->addChild(textTrans);
621   textRedSep->addChild(this->textRedValue);
622 
623   textGreenSep->addChild(pickStyle);
624   textGreenSep->addChild(textGreenColor);
625   textGreenSep->addChild(textTrans);
626   textGreenSep->addChild(this->textGreenValue);
627 
628   textBlueSep->addChild(pickStyle);
629   textBlueSep->addChild(textBlueColor);
630   textBlueSep->addChild(textTrans);
631   textBlueSep->addChild(this->textBlueValue);
632 
633 
634   // build scene graph
635   root->addChild(sep);
636 
637   root->addChild(draggerXTrans);
638   root->addChild(draggerXRotation);
639   root->addChild(draggerX);
640   root->addChild(textRedSep);
641 
642   root->addChild(sep);
643 
644   root->addChild(draggerYTrans);
645   root->addChild(draggerYRotation);
646   root->addChild(draggerY);
647   root->addChild(textGreenSep);
648 
649   root->addChild(sep);
650 
651   root->addChild(draggerZTrans);
652   root->addChild(draggerZRotation);
653   root->addChild(draggerZ);
654   root->addChild(textBlueSep);
655 
656 }
657 
658 
659 
660 void
modifyDraggerWidget(SoScale1Dragger * dragger)661 RGBCubeEditorKitP::modifyDraggerWidget(SoScale1Dragger * dragger)
662 {
663 
664   SoSeparator * newDragger = new SoSeparator;
665   newDragger->ref();
666 
667   SoSeparator * newDraggerActive = new SoSeparator;
668   newDraggerActive->ref();
669 
670   // Optimize all drawing
671   SoShapeHints * draggerHint = new SoShapeHints;
672   draggerHint->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
673   draggerHint->shapeType = SoShapeHints::SOLID;
674   newDragger->addChild(draggerHint);
675   newDraggerActive->addChild(draggerHint);
676 
677 
678   SoCylinder * tube = new SoCylinder;
679   tube->radius=.05;
680   SoRotationXYZ * tubeRot = new SoRotationXYZ;
681   tubeRot->axis = SoRotationXYZ::Z;
682   tubeRot->angle = 3.1415/2;
683 
684   // Passive dragger
685   SoMaterial * passiveMat = new SoMaterial;
686   passiveMat->diffuseColor.setValue(.7,.7,.7);
687   newDragger->addChild(passiveMat);
688   newDragger->addChild(tubeRot);
689   newDragger->addChild(tube);
690 
691   // Active dragger
692   SoMaterial * activeMat = new SoMaterial;
693   activeMat->diffuseColor.setValue(0,1,1);
694   newDraggerActive->addChild(activeMat);
695   newDraggerActive->addChild(tubeRot);
696   newDraggerActive->addChild(tube);
697 
698   // Scaler
699   SoSeparator * newScaler = new SoSeparator;
700   SoMaterial * scaleMat = new SoMaterial;
701   scaleMat->diffuseColor.setValue(0,1,0);
702 
703   SoCube * cube1 = new SoCube; // Axis cross
704   SoCube * cube2 = new SoCube;
705 
706   cube1->width = 0.0;
707   cube1->height = .5;
708   cube1->depth = .1;
709   cube2->width = 0.0;
710   cube2->height = .1;
711   cube2->depth = .5;
712 
713 
714   SoSphere * endPoint = new SoSphere;  // Endpoint ball
715   endPoint->radius = .05;
716 
717   SoAntiSquish * antiSquish = new SoAntiSquish; // Keep aspect ratio!
718   antiSquish->sizing = SoAntiSquish::Y;
719 
720   SoTranslation * endPointTrans1 = new SoTranslation;
721   endPointTrans1->translation.setValue(-1,0,0);
722   SoTranslation * endPointTrans2 = new SoTranslation;
723   endPointTrans2->translation.setValue(1,0,0);
724 
725   SoSeparator * endPoint1Sep = new SoSeparator;
726   SoSeparator * endPoint2Sep = new SoSeparator;
727 
728 
729   // Build scene graph
730   endPoint1Sep->addChild(endPointTrans1);
731   endPoint1Sep->addChild(antiSquish);
732   endPoint1Sep->addChild(endPoint);
733 
734   endPoint2Sep->addChild(endPointTrans2);
735   endPoint2Sep->addChild(antiSquish);
736   endPoint2Sep->addChild(endPoint);
737 
738   newScaler->addChild(scaleMat);
739   newScaler->addChild(cube1);
740   newScaler->addChild(cube2);
741 
742   newScaler->addChild(endPoint1Sep);
743   newScaler->addChild(endPoint2Sep);
744 
745 
746   // Create new draggers
747   dragger->setPart("feedback",newDragger);
748   dragger->setPart("feedbackActive",newDraggerActive);
749 
750   dragger->setPart("scaler",newScaler);
751   dragger->setPart("scalerActive",newScaler);
752 
753 }
754 
755 
756 void
initRgbCube(void)757 RGBCubeEditorKitP::initRgbCube(void)
758 {
759   SoSeparator * root = new SoSeparator;
760   PUBLIC(this)->setPart("RGBCubeRoot",root);
761 
762 
763   SoEventCallback * mouseCallback = new SoEventCallback;
764   mouseCallback->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
765                                   &this->mouseClickCallback, this);
766   root->addChild(mouseCallback);
767 
768 
769   // Creating dragger-text objects
770   this->textRedValue = new SoText2;
771   this->textGreenValue = new SoText2;
772   this->textBlueValue = new SoText2;
773 
774 
775   // Setup diffuse cube geometry
776   this->draggerX =  new SoScale1Dragger;
777   this->draggerY =  new SoScale1Dragger;
778   this->draggerZ =  new SoScale1Dragger;
779 
780 
781   // Modify dragger look
782   this->modifyDraggerWidget(this->draggerX);
783   this->modifyDraggerWidget(this->draggerY);
784   this->modifyDraggerWidget(this->draggerZ);
785 
786 
787   // Create 'o' point translation for cube-corner
788   this->colorIndicatorPosition = new SoTranslation;
789 
790   this->cubeMaterial = new SoMaterial;
791   this->colorCubeCoords = new SoCoordinate3;
792   this->cubeRoot = new SoTransformSeparator;
793   this->initCubeFacelist(this->cubeRoot,
794                          this->colorCubeCoords,
795                          this->cubeMaterial);
796   SoSeparator * cubeRootDraggers = new SoSeparator;
797   this->initCubeDraggers(cubeRootDraggers,
798                          this->draggerX,
799                          this->draggerY,
800                          this->draggerZ,
801                          &this->draggerXCallback,
802                          &this->draggerYCallback,
803                          &this->draggerZCallback,
804                          draggerXValue,
805                          draggerXValue,
806                          draggerXValue);
807   this->cubeRoot->addChild(cubeRootDraggers);
808   this->cubeRoot->ref();
809 
810 
811   root->addChild(this->cubeRoot);
812   draggerCallback();
813 }
814