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 SbSphereProjector SbSphereProjector.h Inventor/projectors/SbSphereProjector.h
35   \brief The SbSphereProjector class is the abstract base class for mapping to spherical surfaces.
36 
37   \ingroup projectors
38 
39   The sphere projectors map 2D points to various surface types based
40   on spherical shapes.
41 
42   \sa SbCylinderProjector
43  */
44 
45 #include <Inventor/projectors/SbSphereProjector.h>
46 
47 /*!
48   \fn SbRotation SbSphereProjector::getRotation(const SbVec3f & point1, const SbVec3f & point2)
49 
50   Returns rotation on the projection surface which re-orients \a
51   point1 to \a point2.
52 */
53 
54 /*!
55   \var SbSphereProjector::intersectFront
56 
57   Flag which says whether or not we should map to the outside or
58   inside of the sphere surface.
59 */
60 /*!
61   \var SbSphereProjector::sphere
62 
63   Projection sphere.
64 */
65 /*!
66   \var SbSphereProjector::orientToEye
67 
68   Which direction the spherical surface is oriented.
69 */
70 /*!
71   \var SbSphereProjector::needSetup
72 
73   Set to \c TRUE whenever the projection surface needs to be
74   recalculated according to the setting of the
75   SbSphereProjector::orientToEye flag.
76 */
77 /*!
78   \var SbSphereProjector::lastPoint
79 
80   Stores the previously projected 3D point.
81 */
82 
83 
84 
85 /*!
86   Default constructor sets up a sphere at the origin with radius 1.
87 */
SbSphereProjector(const SbBool orienttoeye)88 SbSphereProjector::SbSphereProjector(const SbBool orienttoeye)
89   : intersectFront(TRUE),
90     sphere(SbVec3f(0.0f, 0.0f, 0.0f), 1.0f),
91     orientToEye(orienttoeye),
92     needSetup(TRUE),
93     lastPoint(0.0f, 0.0f, 0.0f)
94 {
95 }
96 
97 /*!
98   Constructor taking an explicit \a sphere projection definition.
99 */
SbSphereProjector(const SbSphere & s,const SbBool orienttoeye)100 SbSphereProjector::SbSphereProjector(const SbSphere & s,
101                                      const SbBool orienttoeye)
102   : intersectFront(TRUE),
103     sphere(s),
104     orientToEye(orienttoeye),
105     needSetup(TRUE),
106     lastPoint(0.0f, 0.0f, 0.0f)
107 {
108 }
109 
110 /*!
111   Project the 2D point to a 3D coordinate on the spherical surface,
112   and find the rotation from the last projection to this one.
113 
114   \sa project(), getRotation()
115 */
116 SbVec3f
projectAndGetRotation(const SbVec2f & point,SbRotation & rot)117 SbSphereProjector::projectAndGetRotation(const SbVec2f & point,
118                                          SbRotation & rot)
119 {
120   SbVec3f lastpt = this->lastPoint;
121   SbVec3f newpt = this->project(point);
122   this->lastPoint = newpt;
123   rot = this->getRotation(lastpt, newpt);
124   return newpt;
125 }
126 
127 /*!
128   Set \a sphere to project onto.
129 */
130 void
setSphere(const SbSphere & sph)131 SbSphereProjector::setSphere(const SbSphere & sph)
132 {
133   this->sphere = sph;
134   this->needSetup = TRUE;
135 }
136 
137 /*!
138   Returns projection sphere.
139 */
140 const SbSphere &
getSphere(void) const141 SbSphereProjector::getSphere(void) const
142 {
143   return this->sphere;
144 }
145 
146 /*!
147   Sets whether or not the projection surface should be oriented
148   towards the eye of the viewer. Default is \c TRUE.
149 */
150 void
setOrientToEye(const SbBool orienttoeye)151 SbSphereProjector::setOrientToEye(const SbBool orienttoeye)
152 {
153   this->orientToEye = orienttoeye;
154   this->needSetup = TRUE;
155 }
156 
157 /*!
158   Returns the state of the sphere orientation flag.
159 */
160 SbBool
isOrientToEye(void) const161 SbSphereProjector::isOrientToEye(void) const
162 {
163   return this->orientToEye;
164 }
165 
166 /*!
167   Set whether to intersect with the outside of the sphere (\a infront
168   equal to \c TRUE), or the inside.
169 */
170 void
setFront(const SbBool infront)171 SbSphereProjector::setFront(const SbBool infront)
172 {
173   this->intersectFront = infront;
174   this->needSetup = TRUE;
175 }
176 
177 /*!
178   Returns value of the flag which decides whether to intersect with
179   the outside or inside of the sphere.
180 */
181 SbBool
isFront(void) const182 SbSphereProjector::isFront(void) const
183 {
184   return this->intersectFront;
185 }
186 
187 /*!
188   Check if \a point is on the frontside or the backside of the
189   cylinder.
190 */
191 SbBool
isPointInFront(const SbVec3f & point) const192 SbSphereProjector::isPointInFront(const SbVec3f & point) const
193 {
194   const SbViewVolume & vv = this->getViewVolume();
195   SbVec3f camdir;
196   if (vv.getProjectionType() == SbViewVolume::PERSPECTIVE) {
197     SbVec3f campos;
198     this->worldToWorking.multVecMatrix(vv.getProjectionPoint(), campos);
199     camdir = campos - this->sphere.getCenter();
200 
201     // projection point for reverse perspective view volume lies behind the scene
202     if (vv.getNearDist() < 0.0f) camdir *= -1.0f;
203   }
204   else {
205     this->worldToWorking.multDirMatrix( vv.zVector(), camdir);
206   }
207   SbVec3f ptdir = point - this->sphere.getCenter();
208   return ptdir.dot(camdir) >= 0.0f;
209 }
210 
211 /*!
212   Intersect \a line with the SbSphereProjector::sphere and place the
213   intersection point (if any) in \a result. Considers setFront()
214   settings.
215 
216   Returns \c TRUE if \a line actually hits the sphere, \c FALSE if it
217   doesn't intersect with it.
218 */
219 SbBool
intersectSphereFront(const SbLine & l,SbVec3f & result)220 SbSphereProjector::intersectSphereFront(const SbLine & l, SbVec3f & result)
221 {
222   SbVec3f i0, i1;
223   if (this->sphere.intersect(l, i0, i1)) {
224     if (this->isFront()) result = i0;
225     else result = i1;
226     return TRUE;
227   }
228   return FALSE;
229 }
230 
231 // Documented in superclass.
232 void
setWorkingSpace(const SbMatrix & space)233 SbSphereProjector::setWorkingSpace(const SbMatrix & space)
234 {
235   this->needSetup = TRUE;
236   inherited::setWorkingSpace(space);
237 }
238