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 #include <Inventor/navigation/SoScXMLMiscTarget.h>
34 
35 /*!
36   \class SoScXMLMiscTarget SoScXMLMiscTarget.h Inventor/navigation/SoScXMLMiscTarget.h
37   \brief Some misc navigation utility functions.
38 
39   \ingroup navigation
40 */
41 
42 #include <cassert>
43 
44 #include <Inventor/SbName.h>
45 #include <Inventor/SbViewportRegion.h>
46 #include <Inventor/errors/SoDebugError.h>
47 #include <Inventor/nodes/SoCamera.h>
48 #include <Inventor/scxml/ScXMLEvent.h>
49 #include <Inventor/scxml/SoScXMLStateMachine.h>
50 #include <Inventor/navigation/SoScXMLNavigation.h>
51 #include "coindefs.h"
52 
53 // *************************************************************************
54 
55 class SoScXMLMiscTarget::PImpl {
56 public:
57   static SbName VIEW_ALL;
58   static SbName REDRAW;
59   static SbName POINT_AT;
60   static SbName SET_FOCAL_DISTANCE;
61   static SbName SET_CAMERA_POSITION;
62 
63 };
64 
65 SbName SoScXMLMiscTarget::PImpl::VIEW_ALL;
66 SbName SoScXMLMiscTarget::PImpl::REDRAW;
67 SbName SoScXMLMiscTarget::PImpl::POINT_AT;
68 SbName SoScXMLMiscTarget::PImpl::SET_FOCAL_DISTANCE;
69 SbName SoScXMLMiscTarget::PImpl::SET_CAMERA_POSITION;
70 
71 #define PRIVATE
72 
73 SCXML_OBJECT_SOURCE(SoScXMLMiscTarget);
74 
75 void
initClass(void)76 SoScXMLMiscTarget::initClass(void)
77 {
78   SCXML_OBJECT_INIT_CLASS(SoScXMLMiscTarget, SoScXMLNavigationTarget, "SoScXMLNavigationTarget");
79 
80 #define EVENT_PREFIX SOSCXML_NAVIGATION_MISC_TARGET_EVENT_PREFIX
81   SoScXMLMiscTarget::PImpl::VIEW_ALL             = SbName(EVENT_PREFIX ".VIEW_ALL");
82   SoScXMLMiscTarget::PImpl::REDRAW               = SbName(EVENT_PREFIX ".REDRAW");
83   SoScXMLMiscTarget::PImpl::POINT_AT             = SbName(EVENT_PREFIX ".POINT_AT");
84   SoScXMLMiscTarget::PImpl::SET_FOCAL_DISTANCE   = SbName(EVENT_PREFIX ".SET_FOCAL_DISTANCE");
85   SoScXMLMiscTarget::PImpl::SET_CAMERA_POSITION  = SbName(EVENT_PREFIX ".SET_CAMERA_POSITION");
86 #undef EVENT_PREFIX
87 }
88 
89 void
cleanClass(void)90 SoScXMLMiscTarget::cleanClass(void)
91 {
92   SoScXMLMiscTarget::classTypeId = SoType::badType();
93 }
94 
95 SoScXMLMiscTarget * SoScXMLMiscTarget::theSingleton = NULL;
96 
97 SoScXMLMiscTarget *
constructSingleton(void)98 SoScXMLMiscTarget::constructSingleton(void)
99 {
100   assert(SoScXMLMiscTarget::theSingleton == NULL);
101   SoScXMLMiscTarget::theSingleton =
102     static_cast<SoScXMLMiscTarget *>(SoScXMLMiscTarget::classTypeId.createInstance());
103   return SoScXMLMiscTarget::theSingleton;
104 }
105 
106 void
destructSingleton(void)107 SoScXMLMiscTarget::destructSingleton(void)
108 {
109   assert(SoScXMLMiscTarget::theSingleton != NULL);
110   delete SoScXMLMiscTarget::theSingleton;
111   SoScXMLMiscTarget::theSingleton = NULL;
112 }
113 
114 SoScXMLMiscTarget *
singleton(void)115 SoScXMLMiscTarget::singleton(void)
116 {
117   assert(SoScXMLMiscTarget::theSingleton != NULL);
118   return SoScXMLMiscTarget::theSingleton;
119 }
120 
121 const SbName &
VIEW_ALL(void)122 SoScXMLMiscTarget::VIEW_ALL(void)
123 {
124   return SoScXMLMiscTarget::PImpl::VIEW_ALL;
125 }
126 
127 
128 const SbName &
REDRAW(void)129 SoScXMLMiscTarget::REDRAW(void)
130 {
131   return SoScXMLMiscTarget::PImpl::REDRAW;
132 }
133 
134 
135 const SbName &
POINT_AT(void)136 SoScXMLMiscTarget::POINT_AT(void)
137 {
138   return SoScXMLMiscTarget::PImpl::POINT_AT;
139 }
140 
141 
142 const SbName &
SET_FOCAL_DISTANCE(void)143 SoScXMLMiscTarget::SET_FOCAL_DISTANCE(void)
144 {
145   return SoScXMLMiscTarget::PImpl::SET_FOCAL_DISTANCE;
146 }
147 
148 
149 const SbName &
SET_CAMERA_POSITION(void)150 SoScXMLMiscTarget::SET_CAMERA_POSITION(void)
151 {
152   return SoScXMLMiscTarget::PImpl::SET_CAMERA_POSITION;
153 }
154 
155 
SoScXMLMiscTarget(void)156 SoScXMLMiscTarget::SoScXMLMiscTarget(void)
157 {
158   this->setEventTargetType(SOSCXML_NAVIGATION_TARGETTYPE);
159   this->setEventTargetName("Misc");
160 }
161 
~SoScXMLMiscTarget(void)162 SoScXMLMiscTarget::~SoScXMLMiscTarget(void)
163 {
164 }
165 
166 
167 SbBool
processOneEvent(const ScXMLEvent * event)168 SoScXMLMiscTarget::processOneEvent(const ScXMLEvent * event)
169 {
170   assert(event);
171 
172   const SbName sessionid = this->getSessionId(event);
173   if (sessionid == SbName::empty()) { return FALSE; }
174 
175   const SbName eventname(event->getEventName());
176 
177 #define EVENT_PREFIX SOSCXML_NAVIGATION_MISC_TARGET_EVENT_PREFIX
178   static const SbName VIEW_ALL2(EVENT_PREFIX ".ViewAll");
179   static const SbName REDRAW2(EVENT_PREFIX ".Redraw");
180   static const SbName POINT_AT2(EVENT_PREFIX ".PointAt");
181 #undef EVENT_PREFIX
182 
183   if (eventname == VIEW_ALL() || eventname == VIEW_ALL2 /* compat */) {
184     // _sessionid
185     SoScXMLStateMachine * statemachine = inherited::getSoStateMachine(event, sessionid);
186     if (!statemachine) { return FALSE; }
187 
188     const SbViewportRegion & viewport = statemachine->getViewportRegion();
189     SoCamera * camera = inherited::getActiveCamera(event, sessionid);
190     if (!camera) { return FALSE; }
191 
192     SoNode * scenegraph = statemachine->getSceneGraphRoot();
193     if (!scenegraph) {
194       if (COIN_DEBUG) {
195         SoDebugError::postInfo("SoScXMLMiscTarget::processOneEvent",
196                                "while processing %s: no scene graph set",
197                                eventname.getString());
198       }
199       return FALSE;
200     }
201 
202     camera->viewAll(scenegraph, viewport);
203   }
204 
205   else if (eventname == REDRAW() || eventname == REDRAW2 /* compat */) {
206     // _sessionid
207     SoScXMLStateMachine * statemachine = inherited::getSoStateMachine(event, sessionid);
208     if (!statemachine) { return FALSE; }
209 
210     SoNode * scenegraph = statemachine->getSceneGraphRoot();
211     if (!scenegraph) {
212       if (COIN_DEBUG) {
213         SoDebugError::postInfo("SoScXMLMiscTarget::processOneEvent",
214                                "while processing %s: no scene graph set",
215                                eventname.getString());
216       }
217       return FALSE;
218     }
219 
220     scenegraph->touch();
221   }
222 
223   else if (eventname == POINT_AT() || eventname == POINT_AT2 /* compat */) {
224     // _sessionid
225     // focuspoint || _event.pickposition3 {SbVec3f}
226     // [upvector] {SbVec3f}
227     SoScXMLStateMachine * statemachine = inherited::getSoStateMachine(event, sessionid);
228     if (!statemachine) { return FALSE; }
229 
230     SoCamera * camera = inherited::getActiveCamera(event, sessionid);
231     if (!camera) { return FALSE; }
232 
233     SbVec3f focuspoint;
234     SbBool focusset = FALSE;
235     focusset = inherited::getEventSbVec3f(event, "_event.pickposition3", focuspoint, FALSE);
236     if (!inherited::getEventSbVec3f(event, "focuspoint", focuspoint, !focusset)) {
237       return FALSE;
238     }
239 
240     SbVec3f upvector;
241     SbBool useupvector = inherited::getEventSbVec3f(event, "upvector", upvector, FALSE);
242 
243     if (useupvector) {
244       camera->pointAt(focuspoint, upvector);
245     } else {
246       camera->pointAt(focuspoint);
247     }
248   }
249 
250   else if (eventname == SET_FOCAL_DISTANCE()) {
251     // _sessionid
252     // focaldistance {real}
253     SoScXMLStateMachine * statemachine = inherited::getSoStateMachine(event, sessionid);
254     if (!statemachine) { return FALSE; }
255 
256     SoCamera * camera = inherited::getActiveCamera(event, sessionid);
257     if (!camera) { return FALSE; }
258 
259     double focaldistance;
260     if (!inherited::getEventDouble(event, "focaldistance", focaldistance)) {
261       return FALSE;
262     }
263 
264     camera->focalDistance.setValue(static_cast<float>(focaldistance));
265   }
266 
267   else if (eventname == SET_CAMERA_POSITION()) {
268     // _sessionid
269     // position {SbVec3f}
270 
271     SoScXMLStateMachine * statemachine = inherited::getSoStateMachine(event, sessionid);
272     if (!statemachine) { return FALSE; }
273 
274     SoCamera * camera = inherited::getActiveCamera(event, sessionid);
275     if (!camera) { return FALSE; }
276 
277     SbVec3f position(0.0f, 0.0f, 0.0f);
278     if (!inherited::getEventSbVec3f(event, "position", position)) {
279       return FALSE;
280     }
281 
282     camera->position.setValue(position);
283   }
284 
285   else {
286     SoDebugError::post("SoScXMLMiscTarget::processOneEvent",
287                        "received unknown event '%s'",
288                        eventname.getString());
289     return FALSE;
290   }
291 
292   return TRUE;
293 }
294 
295 #undef PRIVATE
296