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