/src/ogre/OgreMain/include/OgrePatchSurface.h
Line | Count | Source |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef __PatchSurface_H__ |
29 | | #define __PatchSurface_H__ |
30 | | |
31 | | #include "OgrePrerequisites.h" |
32 | | |
33 | | #include "OgreHardwareIndexBuffer.h" |
34 | | #include "OgreHardwareVertexBuffer.h" |
35 | | #include "OgreAxisAlignedBox.h" |
36 | | #include "OgreHeaderPrefix.h" |
37 | | |
38 | | namespace Ogre { |
39 | | |
40 | | /** \addtogroup Core |
41 | | * @{ |
42 | | */ |
43 | | /** \addtogroup LOD |
44 | | * @{ |
45 | | */ |
46 | | /** A surface which is defined by curves of some kind to form a patch, e.g. a Bezier patch. |
47 | | |
48 | | This object will take a list of control points with various assorted data, and will |
49 | | subdivide it into a patch mesh. Currently only Bezier curves are supported for defining |
50 | | the surface, but other techniques such as NURBS would follow the same basic approach. |
51 | | */ |
52 | | class _OgreExport PatchSurface : public PatchAlloc |
53 | | { |
54 | | public: |
55 | | PatchSurface(); |
56 | | ~PatchSurface(); |
57 | | |
58 | | enum PatchSurfaceType |
59 | | { |
60 | | /// A patch defined by a set of bezier curves |
61 | | PST_BEZIER |
62 | | }; |
63 | | |
64 | | /// Constant for indicating automatic determination of subdivision level for patches |
65 | | enum |
66 | | { |
67 | | AUTO_LEVEL = -1 |
68 | | }; |
69 | | |
70 | | enum VisibleSide { |
71 | | /// The side from which u goes right and v goes up (as in texture coords) |
72 | | VS_FRONT, |
73 | | /// The side from which u goes right and v goes down (reverse of texture coords) |
74 | | VS_BACK, |
75 | | /// Both sides are visible - warning this creates 2x the number of triangles and adds extra overhead for calculating normals |
76 | | VS_BOTH |
77 | | }; |
78 | | /** Sets up the surface by defining it's control points, type and initial subdivision level. |
79 | | |
80 | | This method initialises the surface by passing it a set of control points. The type of curves to be used |
81 | | are also defined here, although the only supported option currently is a bezier patch. You can also |
82 | | specify a global subdivision level here if you like, although it is recommended that the parameter |
83 | | is left as AUTO_LEVEL, which means the system decides how much subdivision is required (based on the |
84 | | curvature of the surface) |
85 | | @param |
86 | | controlPointBuffer A pointer to a buffer containing the vertex data which defines control points |
87 | | of the curves rather than actual vertices. Note that you are expected to provide not |
88 | | just position information, but potentially normals and texture coordinates too. The |
89 | | format of the buffer is defined in the VertexDeclaration parameter |
90 | | @param |
91 | | declaration VertexDeclaration describing the contents of the buffer. |
92 | | Note this declaration must _only_ draw on buffer source 0! |
93 | | @param |
94 | | width Specifies the width of the patch in control points. |
95 | | @param |
96 | | height Specifies the height of the patch in control points. |
97 | | @param |
98 | | pType The type of surface - currently only PST_BEZIER is supported |
99 | | @param |
100 | | uMaxSubdivisionLevel,vMaxSubdivisionLevel If you want to manually set the top level of subdivision, |
101 | | do it here, otherwise let the system decide. |
102 | | @param |
103 | | visibleSide Determines which side of the patch (or both) triangles are generated for. |
104 | | */ |
105 | | void defineSurface(void* controlPointBuffer, |
106 | | VertexDeclaration *declaration, size_t width, size_t height, |
107 | | PatchSurfaceType pType = PST_BEZIER, |
108 | | size_t uMaxSubdivisionLevel = AUTO_LEVEL, size_t vMaxSubdivisionLevel = AUTO_LEVEL, |
109 | | VisibleSide visibleSide = VS_FRONT); |
110 | | |
111 | | /** Based on a previous call to defineSurface, establishes the number of vertices required |
112 | | to hold this patch at the maximum detail level. |
113 | | @remarks This is useful when you wish to build the patch into external vertex / index buffers. |
114 | | |
115 | | */ |
116 | | size_t getRequiredVertexCount(void) const; |
117 | | /** Based on a previous call to defineSurface, establishes the number of indexes required |
118 | | to hold this patch at the maximum detail level. |
119 | | @remarks This is useful when you wish to build the patch into external vertex / index buffers. |
120 | | |
121 | | */ |
122 | | size_t getRequiredIndexCount(void) const; |
123 | | |
124 | | /** Gets the current index count based on the current subdivision level. */ |
125 | | size_t getCurrentIndexCount(void) const; |
126 | | /// Returns the index offset used by this buffer to write data into the buffer |
127 | 0 | size_t getIndexOffset(void) const { return mIndexOffset; } |
128 | | /// Returns the vertex offset used by this buffer to write data into the buffer |
129 | 0 | size_t getVertexOffset(void) const { return mVertexOffset; } |
130 | | |
131 | | |
132 | | /** Gets the bounds of this patch, only valid after calling defineSurface. */ |
133 | | const AxisAlignedBox& getBounds(void) const; |
134 | | /** Gets the radius of the bounding sphere for this patch, only valid after defineSurface |
135 | | has been called. */ |
136 | | Real getBoundingSphereRadius(void) const; |
137 | | /** Tells the system to build the mesh relating to the surface into externally created |
138 | | buffers. |
139 | | |
140 | | The VertexDeclaration of the vertex buffer must be identical to the one passed into |
141 | | defineSurface. In addition, there must be enough space in the buffer to |
142 | | accommodate the patch at full detail level; you should call getRequiredVertexCount |
143 | | and getRequiredIndexCount to determine this. This method does not create an internal |
144 | | mesh for this patch and so getMesh will return null if you call it after building the |
145 | | patch this way. |
146 | | @param destVertexBuffer The destination vertex buffer in which to build the patch. |
147 | | @param vertexStart The offset at which to start writing vertices for this patch |
148 | | @param destIndexBuffer The destination index buffer in which to build the patch. |
149 | | @param indexStart The offset at which to start writing indexes for this patch |
150 | | |
151 | | */ |
152 | | void build(HardwareVertexBufferSharedPtr destVertexBuffer, size_t vertexStart, |
153 | | HardwareIndexBufferSharedPtr destIndexBuffer, size_t indexStart); |
154 | | |
155 | | /** Alters the level of subdivision for this surface. |
156 | | |
157 | | This method changes the proportionate detail level of the patch; since |
158 | | the U and V directions can have different subdivision levels, this method |
159 | | takes a single Real value where 0 is the minimum detail (the control points) |
160 | | and 1 is the maximum detail level as supplied to the original call to |
161 | | defineSurface. |
162 | | */ |
163 | | void setSubdivisionFactor(Real factor); |
164 | | |
165 | | /** Gets the current level of subdivision. */ |
166 | | Real getSubdivisionFactor(void) const; |
167 | | |
168 | | void* getControlPointBuffer(void) const |
169 | 0 | { |
170 | 0 | return mControlPointBuffer; |
171 | 0 | } |
172 | | /** Convenience method for telling the patch that the control points have been |
173 | | deleted, since once the patch has been built they are not required. */ |
174 | 0 | void notifyControlPointBufferDeallocated(void) { |
175 | 0 | mControlPointBuffer = 0; |
176 | 0 | } |
177 | | private: |
178 | | /// Vertex declaration describing the control point buffer |
179 | | VertexDeclaration* mDeclaration; |
180 | | /// Buffer containing the system-memory control points |
181 | | void* mControlPointBuffer; |
182 | | /// Type of surface |
183 | | PatchSurfaceType mType; |
184 | | /// Width in control points |
185 | | size_t mCtlWidth; |
186 | | /// Height in control points |
187 | | size_t mCtlHeight; |
188 | | /// TotalNumber of control points |
189 | | size_t mCtlCount; |
190 | | /// U-direction subdivision level |
191 | | size_t mULevel; |
192 | | /// V-direction subdivision level |
193 | | size_t mVLevel; |
194 | | /// Max subdivision level |
195 | | size_t mMaxULevel; |
196 | | size_t mMaxVLevel; |
197 | | /// Width of the subdivided mesh (big enough for max level) |
198 | | size_t mMeshWidth; |
199 | | /// Height of the subdivided mesh (big enough for max level) |
200 | | size_t mMeshHeight; |
201 | | /// Which side is visible |
202 | | VisibleSide mVSide; |
203 | | |
204 | | Real mSubdivisionFactor; |
205 | | |
206 | | std::vector<Vector3> mVecCtlPoints; |
207 | | |
208 | | /** Internal method for finding the subdivision level given 3 control points. |
209 | | */ |
210 | | size_t findLevel( Vector3& a, Vector3& b, Vector3& c); |
211 | | |
212 | | void distributeControlPoints(void* lockedBuffer); |
213 | | void subdivideCurve(void* lockedBuffer, size_t startIdx, size_t stepSize, size_t numSteps, size_t iterations); |
214 | | void interpolateVertexData(void* lockedBuffer, size_t leftIndex, size_t rightIndex, size_t destIndex); |
215 | | void makeTriangles(void); |
216 | | |
217 | | size_t getAutoULevel(bool forMax = false); |
218 | | size_t getAutoVLevel(bool forMax = false); |
219 | | |
220 | | HardwareVertexBufferSharedPtr mVertexBuffer; |
221 | | HardwareIndexBufferSharedPtr mIndexBuffer; |
222 | | size_t mVertexOffset; |
223 | | size_t mIndexOffset; |
224 | | size_t mRequiredVertexCount; |
225 | | size_t mRequiredIndexCount; |
226 | | size_t mCurrIndexCount; |
227 | | |
228 | | AxisAlignedBox mAABB; |
229 | | Real mBoundingSphere; |
230 | | |
231 | | |
232 | | |
233 | | }; |
234 | | |
235 | | /** @} */ |
236 | | /** @} */ |
237 | | |
238 | | } // namespace |
239 | | |
240 | | #include "OgreHeaderSuffix.h" |
241 | | |
242 | | #endif |