00001 /* 00002 * prism.h 00003 * 00004 * Copyright (C) 2010 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * 3D Prisms 00032 */ 00033 00034 #ifndef WAVEPACKET_PRISM_H__ 00035 #define WAVEPACKET_PRISM_H__ 00036 00037 // includes -------------------------------------------------------------------- 00038 #include "geometry_3d.h" 00039 #include "matrix_4.h" 00040 00041 00042 /// \ingroup geometry 00043 /*@{*/ 00044 00045 00046 /// a prism is a 3D object, basically a polygon in some plane with some 00047 /// extent in the plane normal direction. See wikipedia for the general 00048 /// definition: http://en.wikipedia.org/wiki/Prism_(geometry) 00049 /// In particular, this is a \b right prism. 00050 /// This class (prism_base_t) is templated, so that the client can decide the 00051 /// max size of the vertex array. Given a polygonal base of N points, you 00052 /// will need 2N vertices. 00053 /// The array of points has a specific convention: 00054 /// point[2 * i] is the vertex on the "floor" (y = 0) 00055 /// point[(2 * i) + 1] is the vertex on the ceiling (y = height above the 00056 /// point[2 * i] vertex) 00057 /// So for instance, any consecutive sequence of 4 points starting with even 00058 /// index is guaranteed to be a planar rectangle. This is a very helpful 00059 /// property of prisms. 00060 /// \b WARNING: the xz-plane, y-extent convention is recommended for basic 00061 /// prisms. However, prisms can be transformed by arbitrary 3D 00062 /// transformations (see matrix4_t). So you can't assume that an 00063 /// odd-indexed point is only translated in the y-direction from its 00064 /// even-indexed base, for instance. However, consecutive sequences of 4 00065 /// points starting with even index will always be a planar rectangle, even 00066 /// when transformed. 00067 template <class Size> 00068 struct prism_base_t { 00069 // constructor, manipulators 00070 prism_base_t(void) throw() { this->clear(); } 00071 void clear(void) throw() { 00072 nVertices = 0; 00073 } 00074 bool isValid(void) const throw() { 00075 return (nVertices > 2) && 00076 (2 * nVertices < Size::eMaxCount); 00077 } 00078 void setVertexCount(IN int N) { 00079 ASSERT_THROW(N > 5 && // at least 3-sided 00080 (0 == (N % 2)) && // must be even 00081 N <= Size::eMaxCount, 00082 "Invalid prism vertex count: " << N); 00083 nVertices = N; 00084 } 00085 00086 // data fields 00087 point3d_t points[Size::eMaxCount]; 00088 int nVertices; 00089 }; 00090 00091 00092 00093 class DefaultSize { 00094 public: 00095 enum eConstants { 00096 eMaxCount = 16 00097 }; 00098 }; 00099 00100 00101 00102 /// a default prism class, supporting up to 16 points (supports prisms based 00103 /// on polygons up to 8 sides). 00104 typedef prism_base_t<DefaultSize> prism_t; 00105 00106 00107 00108 /// creates a 3D prism whose base is a regular N-polygon, with specified radius 00109 /// and height. Caller must provide an array big enough to hold 2*nSides 00110 /// points. That array is populated on output. The polygons are in the 00111 /// xz plane, separated by distance height in the y direction. 00112 void createRegularPrism(IN int nSides, 00113 IN float radius, 00114 IN float height, 00115 IO point3d_t * points); 00116 00117 00118 00119 /// helper method to create a regular prism 00120 template <class Size> 00121 void createRegularPrism 00122 ( 00123 IN int nSides, 00124 IN float radius, 00125 IN float height, 00126 OUT prism_base_t<Size>& prism 00127 ) 00128 { 00129 prism.setVertexCount(2 * nSides); 00130 createRegularPrism(nSides, radius, height, prism.points); 00131 } 00132 00133 00134 00135 /// transforms a prism by a matrix4_t transformation 00136 template <class Size> 00137 prism_base_t<Size> 00138 operator * 00139 ( 00140 IN const matrix4_t& T, 00141 IN const prism_base_t<Size>& prism 00142 ) 00143 { 00144 ASSERT_THROW(prism.isValid(), "Invalid prism being transformed"); 00145 prism_base_t<Size> outPrism; 00146 outPrism.setVertexCount(prism.nVertices); 00147 transformPoints(T, prism.nVertices, prism.points, outPrism.points); 00148 return outPrism; 00149 } 00150 00151 00152 00153 #endif // WAVEPACKET_PRISM_H__ 00154