1 /*
2 * Copyright (C) 1997-2005, R3vis Corporation.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18 *
19 * Original Contributor:
20 * Wes Bethel, R3vis Corporation, Marin County, California
21 * Additional Contributor(s):
22 *
23 * The OpenRM project is located at http://openrm.sourceforge.net/.
24 */
25 /*
26 * $Id: rmclip.c,v 1.7 2005/02/19 16:22:50 wes Exp $
27 * Version: $Name: OpenRM-1-6-0-2-RC2 $
28 * $Revision: 1.7 $
29 * $Log: rmclip.c,v $
30 * Revision 1.7 2005/02/19 16:22:50 wes
31 * Distro sync and consolidation.
32 *
33 * Revision 1.6 2005/02/12 00:53:25 wes
34 * Minor code reorgs (from RMSG).
35 *
36 * Revision 1.5 2005/01/23 17:00:22 wes
37 * Copyright updated to 2005.
38 *
39 * Revision 1.4 2004/01/16 16:43:24 wes
40 * Updated copyright line for 2004.
41 *
42 * Revision 1.3 2003/07/06 16:22:13 wes
43 * Bug fix: rmClipPlaneSetPointNormal was always returning RM_WHACKED.
44 * (Thanks to A. Yarnos for reporting this buglet).
45 *
46 * Revision 1.2 2003/02/02 02:07:15 wes
47 * Updated copyright to 2003.
48 *
49 * Revision 1.1.1.1 2003/01/28 02:15:23 wes
50 * Manual rebuild of rm150 repository.
51 *
52 * Revision 1.5 2003/01/16 22:21:17 wes
53 * Updated all source files to reflect new organization of header files:
54 * all header files formerly located in include/rmaux, include/rmi, include/rmv
55 * are now located in include/rm.
56 *
57 * Revision 1.4 2002/04/30 19:29:18 wes
58 * Updated copyright dates.
59 *
60 * Revision 1.3 2001/03/31 17:12:38 wes
61 * v1.4.0-alpha-2 checkin.
62 *
63 * Revision 1.2 2000/04/20 16:29:47 wes
64 * Documentation additions/enhancements, some code rearragement.
65 *
66 * Revision 1.1.1.1 2000/02/28 21:29:40 wes
67 * OpenRM 1.2 Checkin
68 *
69 * Revision 1.1.1.1 2000/02/28 17:18:47 wes
70 * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
71 *
72 */
73
74 #include <rm/rm.h>
75 #include "rmprivat.h"
76
77 /*
78 * ----------------------------------------------------
79 * @Name rmClipPlaneNew
80 @pstart
81 RMclipPlane * rmClipPlaneNew (void)
82 @pend
83
84 @astart
85 no arguments.
86 @aend
87
88 @dstart
89
90 Creates a new RMclipPlane object, returning a handle to the new
91 RMclipPlane object upon success, or NULL upon failure.
92
93 The new RMclipPlane object is initialized with the following default
94 values:
95
96 1. The RMclipPlane object is disabled.
97
98 2. Default point: (RM_DEFAULT_CLIP_PLANE_POINT) {0.,0.,0.}
99
100 3. Default normal: (RM_DEFAULT_CLIP_PLANE_NORMAL) {0., 0., -1.}
101
102 Applications should use rmClipPlaneDelete to release resources
103 associated with the RMclipPlane object when no longer needed.
104
105 To have the clip plane used during rendering, it needs to be
106 activated (rmClipPlaneEnable), assigned whatever values you want for
107 the point and normal attributes (normalized normals, please) and then
108 assigned as a scene parameter to an RMnode with
109 rmNodeSetSceneClipPlane.
110
111 @dend
112 * ----------------------------------------------------
113 */
114 RMclipPlane *
rmClipPlaneNew(void)115 rmClipPlaneNew (void)
116 {
117 RMclipPlane *cp;
118 extern RMvertex3D RM_DEFAULT_CLIP_PLANE_POINT, RM_DEFAULT_CLIP_PLANE_NORMAL;
119
120 cp = (RMclipPlane *)malloc(sizeof(RMclipPlane));
121 if (cp == NULL)
122 {
123 rmError("rmClipPlaneNew() error: can't malloc memory for a clip plane object.");
124 return(NULL);
125 }
126 rmClipPlaneSetPointNormal(cp, &RM_DEFAULT_CLIP_PLANE_POINT, &RM_DEFAULT_CLIP_PLANE_NORMAL);
127 rmClipPlaneDisable(cp);
128
129 return(cp);
130 }
131
132
133 /*
134 * ----------------------------------------------------
135 * @Name rmClipPlaneDelete
136 @pstart
137 RMenum rmClipPlaneDelete (RMclipPlane *toDelete)
138 @pend
139
140 @astart
141 RMclipPlane *toDelete - a handle to the RMclipPlane object to be
142 deleted.
143 @aend
144
145 @dstart
146
147 This routine releases RMclipPlane resources, the opposite of
148 rmClipPlaneNew.
149
150 Upon success, RM_CHILL is returned and the rmclipPlance has been
151 deleted. Otherwise, RM_WHACKED is returned.
152
153 @dend
154 * ----------------------------------------------------
155 */
156 RMenum
rmClipPlaneDelete(RMclipPlane * cp)157 rmClipPlaneDelete (RMclipPlane *cp)
158 {
159 if (RM_ASSERT(cp, "rmClipPlaneDelete() error: input clip plane object pointer is NULL.") == RM_WHACKED)
160 return(RM_WHACKED);
161
162 free((void *)cp);
163
164 return(RM_CHILL);
165 }
166
167
168 /*
169 * ----------------------------------------------------
170 * @Name rmClipPlaneSetPointNormal
171 @pstart
172 RMenum rmClipPlaneSetPointNormal (RMclipPlane *toModify,
173 const RMvertex3D *point,
174 const RMvertex3D *normal)
175 @pend
176
177 @astart
178 RMclipPlane *toModify - a handle to an RMclipPlane object that will
179 be modified (input and result).
180
181 RMvertex3D *point - a handle to a caller supplied RMvertex3D object.
182 The contents of the caller's "point" value will be copied into the
183 RMclipPlane's "point" attribute.
184
185 RMvertex3D *normal - a handle to a caller supplied RMvertex3D object.
186 The contents of the caller's "normal" value will be copied into
187 the RMclipPlane's "normal" attribute.
188 @aend
189
190 @dstart
191
192 A clipping plane in OpenRM is defined with two parameters, a 3D point
193 and a normal.
194
195 Use this routine to set these parameters in an RMclipPlane object.
196
197 @dend
198 * ----------------------------------------------------
199 */
200 RMenum
rmClipPlaneSetPointNormal(RMclipPlane * cp,const RMvertex3D * point,const RMvertex3D * normal)201 rmClipPlaneSetPointNormal (RMclipPlane *cp,
202 const RMvertex3D *point,
203 const RMvertex3D *normal)
204 {
205 float d;
206 RMvertex3D ln, lp;
207
208 if ((RM_ASSERT(cp, "rmClipPlaneSetPointNormal() error: the input clip plane pointer is NULL.") == RM_WHACKED) ||
209 (RM_ASSERT(point, "rmClipPlaneSetPointNormal() error: the input point parameter is NULL. ") == RM_WHACKED) ||
210 (RM_ASSERT(normal, "rmClipPlaneSetPointNormal() error: the input normal parameter is NULL ") == RM_WHACKED))
211 return(RM_WHACKED);
212
213 /* copy over vertex info for local use */
214 cp->point = lp = *point;
215 cp->normal = ln = *normal;
216 rmVertex3DNormalize(&ln);
217
218 /* compute a,b,c,d planar coefficients from the point-normal form.
219 we assume that the normal is normalized */
220 d = (ln.x * lp.x) + (ln.y * lp.y) + (ln.z * lp.z);
221 d *= -1.0;
222
223 /* store the planar coefficients */
224 cp->a = ln.x;
225 cp->b = ln.y;
226 cp->c = ln.z;
227 cp->d = d;
228
229 return(RM_CHILL);
230 }
231
232
233 /*
234 * ----------------------------------------------------
235 * @Name rmClipPlaneGetPointNormal
236 @pstart
237 RMenum rmClipPlaneGetPointNormal (const RMclipPlane *toQuery,
238 RMvertex3D *point,
239 RMvertex3D *normal)
240 @pend
241
242 @astart
243 const RMclipPlane *toQuery - a handle to an RMclipPlane object that
244 will be queried (input).
245
246 RMvertex3D *point - a handle to a caller supplied RMvertex3D object.
247 The RMclipPlane's "point" attribute will be copied into this
248 object (result).
249
250 RMvertex3D *normal - a handle to a caller supplied RMvertex3D object.
251 The RMclipPlane's "normal" attribute will be copied into this
252 object (result).
253 @aend
254
255 @dstart
256
257 A clipping plane in OpenRM is defined with two parameters, a 3D point
258 and a normal.
259
260 Use this routine to obtain these parameters from an RMclipPlane
261 object.
262
263 @dend
264 * ----------------------------------------------------
265 */
266 RMenum
rmClipPlaneGetPointNormal(const RMclipPlane * cp,RMvertex3D * point,RMvertex3D * normal)267 rmClipPlaneGetPointNormal (const RMclipPlane *cp,
268 RMvertex3D *point,
269 RMvertex3D *normal)
270 {
271 if ((RM_ASSERT(cp, "rmClipPlaneGetPointNormal() error: the input clip plane pointer is NULL.") == RM_WHACKED) ||
272 (RM_ASSERT(point, "rmClipPlaneGetPointNormal() error: the input point parameter is NULL. ") == RM_WHACKED) ||
273 (RM_ASSERT(normal, "rmClipPlaneGetPointNormal() error: the input normal parameter is NULL ") == RM_WHACKED))
274 return(RM_WHACKED);
275
276 VCOPY(&(cp->point), point);
277 VCOPY(&(cp->normal), normal);
278
279 return(RM_CHILL);
280 }
281
282
283 /*
284 * ----------------------------------------------------
285 * @Name rmClipPlaneEnable
286 @pstart
287 RMenum rmClipPlaneEnable (RMclipPlane *toModify)
288 @pend
289
290 @astart
291 RMclipPlane *toModify - a handle to an RMclipPlane object. This
292 object will be modified by this routine.
293 @aend
294
295 @dstart
296
297 Use this routine to "turn on" a clipping plane.
298
299 Clipping planes are scene parameters assigned to RMnodes. Upon
300 assignment, OpenRM makes a copy of the caller-supplied RMclipPlane
301 object. Any application changes to the RMclipPlane object do not
302 affect the copy of the RMclipPlane at the RMnode: after making
303 changes, the RMclipPlane object must be reassigned to the RMnode as a
304 scene parameter (see rmNodeSetSceneClipPlane()). Therefore, if the
305 application maintains it's own internal array of clipping planes, any
306 changes to the application RMclipPlane objects should be propogated
307 to OpenRM with rmNodeSetSceneClipPlane, including deactivation.
308
309 See also rmClipPlaneNew().
310
311 @dend
312 * ----------------------------------------------------
313 */
314 RMenum
rmClipPlaneEnable(RMclipPlane * cp)315 rmClipPlaneEnable (RMclipPlane *cp)
316 {
317 if (RM_ASSERT(cp, "rmClipPlaneEnable() error: input clip plane object pointer is NULL.") == RM_WHACKED)
318 return(RM_WHACKED);
319
320 cp->enabled = RM_TRUE;
321
322 return(RM_CHILL);
323 }
324
325
326 /*
327 * ----------------------------------------------------
328 * @Name rmClipPlaneDisable
329 @pstart
330 RMenum rmClipPlaneDisable (RMclipPlane *toModify)
331 @pend
332
333 @astart
334 RMclipPlane *toModify - a handle to an RMclipPlane object. This
335 object will be modified by this routine.
336 @aend
337
338 @dstart
339
340 Use this routine to "turn off" a clipping plane.
341
342 Clipping planes are scene parameters assigned to RMnodes. Upon
343 assignment, OpenRM makes a copy of the caller-supplied RMclipPlane
344 object. Any application changes to the RMclipPlane object do not
345 affect the copy of the RMclipPlane at the RMnode: after making
346 changes, the RMclipPlane object must be reassigned to the RMnode as a
347 scene parameter (see rmNodeSetSceneClipPlane()). Therefore, if the
348 application maintains it's own internal array of clipping planes, any
349 changes to the application RMclipPlane objects should be propogated
350 to OpenRM with rmNodeSetSceneClipPlane, including deactivation.
351
352 Applications may deactivate a clip plane by either 1. calling this
353 routine to set an RMclipPlane's active attribute to "off" and then
354 propogating the modified RMclipPlane to a scene graph node with
355 rmNodeSetSceneClipPlane, or 2. by removing the clip plane from a
356 scene graph node by calling rmNodeSetSceneClipPlane with NULL as the
357 value for the RMclipPlane parameter.
358
359 @dend
360 * ----------------------------------------------------
361 */
362 RMenum
rmClipPlaneDisable(RMclipPlane * cp)363 rmClipPlaneDisable (RMclipPlane *cp)
364 {
365 if (RM_ASSERT(cp, "rmClipPlaneDisable() error: input clip plane object pointer is NULL.") == RM_WHACKED)
366 return(RM_WHACKED);
367
368 cp->enabled = RM_FALSE;
369 return(RM_CHILL);
370 }
371
372
373 /*
374 * ----------------------------------------------------
375 * @Name rmClipPlaneIsEnabled
376 @pstart
377 RMenum rmClipPlaneIsEnabled (const RMclipPlane *toQuery)
378 @pend
379
380 @astart
381 const RMclipPlane *toQuery
382 @aend
383
384 @dstart
385
386 This routine is will return to the caller RM_TRUE if the RMclipPlane
387 object is "enabled", or RM_FALSE if the RMclipPlane object is
388 disabled. RM_WHACKED is returned if the RMclipPlane object is NULL.
389
390 @dend
391 * ----------------------------------------------------
392 */
393 RMenum
rmClipPlaneIsEnabled(const RMclipPlane * cp)394 rmClipPlaneIsEnabled (const RMclipPlane *cp)
395 {
396 if (RM_ASSERT(cp, "rmClipPlaneIsEnabled() error: input clip plane object pointer is NULL.") == RM_WHACKED)
397 return(RM_WHACKED);
398
399 return(cp->enabled);
400 }
401 /* EOF */
402