NOW I do it right: #woxblox#
[divverent/netradiant.git] / include / ipatch.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_IPATCH_H)
23 #define INCLUDED_IPATCH_H
24
25 #include "generic/constant.h"
26 #include "generic/vector.h"
27
28 namespace scene
29 {
30   class Node;
31 }
32
33 template<typename Element>
34 class ArrayReference
35 {
36   std::size_t m_size;
37   Element* m_data;
38 public:
39   typedef Element value_type;
40   typedef value_type* iterator;
41   typedef const value_type* const_iterator;
42
43   ArrayReference()
44     : m_size(0), m_data(0)
45   {
46   }
47   ArrayReference(std::size_t size, Element* data)
48     : m_size(size), m_data(data)
49   {
50   }
51
52   iterator begin()
53   {
54     return m_data;
55   }
56   const_iterator begin() const
57   {
58     return m_data;
59   }
60   iterator end()
61   {
62     return m_data + m_size;
63   }
64   const_iterator end() const
65   {
66     return m_data + m_size;
67   }
68
69   value_type& operator[](std::size_t index)
70   {
71 #if defined(_DEBUG)
72     ASSERT_MESSAGE(index < size(), "array index out of bounds");
73 #endif
74     return m_data[index];
75   }
76   const value_type& operator[](std::size_t index) const
77   {
78 #if defined(_DEBUG)
79     ASSERT_MESSAGE(index < size(), "array index out of bounds");
80 #endif
81     return m_data[index];
82   }
83   value_type* data()
84   {
85     return m_data;
86   }
87   const value_type* data() const
88   {
89     return m_data;
90   }
91   std::size_t size() const
92   {
93     return m_size;
94   }
95   bool empty() const
96   {
97     return m_size == 0;
98   }
99 };
100
101 #if 0
102 template<typename Element>
103 class MatrixIterator
104 {
105   Element* m_position;
106
107   void increment()
108   {
109     ++m_position;
110   }
111
112 public:
113   typedef std::bidirectional_iterator_tag iterator_category;
114   typedef std::ptrdiff_t difference_type;
115   typedef difference_type distance_type;
116   typedef KeyValue<Key, Value> value_type;
117   typedef value_type* pointer;
118   typedef value_type& reference;
119
120   MatrixIterator(Element* position) : m_position(position)
121   {
122   }
123
124   Element* position()
125   {
126     return m_position;
127   }
128
129   bool operator==(const MatrixIterator& other) const
130   {
131     return m_position == other.m_position;
132   }
133   bool operator!=(const MatrixIterator& other) const
134   {
135     return !operator==(other);
136   }
137   MatrixIterator& operator++()
138   {
139     increment();
140     return *this;
141   }
142   MatrixIterator operator++(int)
143   {
144     MatrixIterator tmp = *this;
145     increment();
146     return tmp;
147   }
148   value_type& operator*() const
149   {
150     return m_position->m_value;
151   }
152   value_type* operator->() const
153   {
154     return &(operator*());
155   }
156 };
157 #endif
158
159 template<typename Element>
160 class Matrix
161 {
162   std::size_t m_x, m_y;
163   Element* m_data;
164 public:
165   typedef Element value_type;
166   typedef value_type* iterator;
167   typedef const value_type* const_iterator;
168
169   Matrix()
170     : m_x(0), m_y(0), m_data(0)
171   {
172   }
173   Matrix(std::size_t x, std::size_t y, Element* data)
174     : m_x(x), m_y(y), m_data(data)
175   {
176   }
177
178   iterator begin()
179   {
180     return m_data;
181   }
182   const_iterator begin() const
183   {
184     return m_data;
185   }
186   iterator end()
187   {
188     return m_data + size();
189   }
190   const_iterator end() const
191   {
192     return m_data + size();
193   }
194
195   value_type& operator[](std::size_t index)
196   {
197 #if defined(_DEBUG)
198     ASSERT_MESSAGE(index < size(), "array index out of bounds");
199 #endif
200     return m_data[index];
201   }
202   const value_type& operator[](std::size_t index) const
203   {
204 #if defined(_DEBUG)
205     ASSERT_MESSAGE(index < size(), "array index out of bounds");
206 #endif
207     return m_data[index];
208   }
209   value_type& operator()(std::size_t x, std::size_t y)
210   {
211 #if defined(_DEBUG)
212     ASSERT_MESSAGE(x < m_x && y < m_y, "array index out of bounds");
213 #endif
214     return m_data[x * m_y + y];
215   }
216   const value_type& operator()(std::size_t x, std::size_t y) const
217   {
218 #if defined(_DEBUG)
219     ASSERT_MESSAGE(x < m_x && y < m_y, "array index out of bounds");
220 #endif
221     return m_data[x * m_y + y];
222   }
223   value_type* data()
224   {
225     return m_data;
226   }
227   const value_type* data() const
228   {
229     return m_data;
230   }
231   std::size_t x() const
232   {
233     return m_x;
234   }
235   std::size_t y() const
236   {
237     return m_y;
238   }
239   std::size_t size() const
240   {
241     return m_x * m_y;
242   }
243   bool empty() const
244   {
245     return m_x == 0;
246   }
247 };
248
249 class PatchControl
250 {
251 public:
252   Vector3 m_vertex;
253   Vector2 m_texcoord;
254 };
255
256 typedef Matrix<PatchControl> PatchControlMatrix;
257
258
259 class PatchCreator
260 {
261 public:
262   INTEGER_CONSTANT(Version, 1);
263   STRING_CONSTANT(Name, "patch");
264   virtual scene::Node& createPatch() = 0;
265   virtual void Patch_undoSave(scene::Node& patch) const = 0;
266   virtual void Patch_resize(scene::Node& patch, std::size_t width, std::size_t height) const = 0;
267   virtual PatchControlMatrix Patch_getControlPoints(scene::Node& patch) const = 0;
268   virtual void Patch_controlPointsChanged(scene::Node& patch) const = 0;
269   virtual const char* Patch_getShader(scene::Node& patch) const = 0;
270   virtual void Patch_setShader(scene::Node& patch, const char* shader) const = 0;
271 };
272
273 #include "modulesystem.h"
274
275 template<typename Type>
276 class ModuleRef;
277 typedef ModuleRef<PatchCreator> PatchModuleRef;
278
279 template<typename Type>
280 class GlobalModule;
281 typedef GlobalModule<PatchCreator> GlobalPatchModule;
282
283 template<typename Type>
284 class GlobalModuleRef;
285 typedef GlobalModuleRef<PatchCreator> GlobalPatchModuleRef;
286
287 inline PatchCreator& GlobalPatchCreator()
288 {
289   return GlobalPatchModule::getTable();
290 }
291
292 #endif