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