2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
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.
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.
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
22 #if !defined(INCLUDED_SELECTABLE_H)
23 #define INCLUDED_SELECTABLE_H
27 #include "math/vector.h"
30 class SelectionIntersection
35 SelectionIntersection() : m_depth(1), m_distance(2)
38 SelectionIntersection(float depth, float distance) : m_depth(depth), m_distance(distance)
41 bool operator<(const SelectionIntersection& other) const
43 if(m_distance != other.m_distance)
45 return m_distance < other.m_distance;
47 if(m_depth != other.m_depth)
49 return m_depth < other.m_depth;
53 bool equalEpsilon(const SelectionIntersection& other, float distanceEpsilon, float depthEpsilon) const
55 return float_equal_epsilon(m_distance, other.m_distance, distanceEpsilon)
56 && float_equal_epsilon(m_depth, other.m_depth, depthEpsilon);
68 // returns true if self is closer than other
69 inline bool SelectionIntersection_closer(const SelectionIntersection& self, const SelectionIntersection& other)
74 // assigns other to best if other is closer than best
75 inline void assign_if_closer(SelectionIntersection& best, const SelectionIntersection& other)
77 if(SelectionIntersection_closer(other, best))
88 typedef const unsigned char* byte_pointer;
90 typedef float elem_type;
91 typedef const elem_type* pointer;
92 typedef const elem_type& reference;
98 iterator(byte_pointer vertices, std::size_t stride)
99 : m_iter(vertices), m_stride(stride) {}
101 bool operator==(const iterator& other) const
103 return m_iter == other.m_iter;
105 bool operator!=(const iterator& other) const
107 return !operator==(other);
110 iterator operator+(std::size_t i)
112 return iterator(m_iter + i * m_stride, m_stride);
114 iterator operator+=(std::size_t i)
116 m_iter += i * m_stride;
119 iterator& operator++()
124 iterator operator++(int)
126 iterator tmp = *this;
130 reference operator*() const
132 return *reinterpret_cast<pointer>(m_iter);
136 std::size_t m_stride;
139 VertexPointer(pointer vertices, std::size_t stride)
140 : m_vertices(reinterpret_cast<byte_pointer>(vertices)), m_stride(stride) {}
142 iterator begin() const
144 return iterator(m_vertices, m_stride);
147 reference operator[](std::size_t i) const
149 return *reinterpret_cast<pointer>(m_vertices + m_stride*i);
153 byte_pointer m_vertices;
154 std::size_t m_stride;
160 typedef unsigned int index_type;
161 typedef const index_type* pointer;
166 iterator(pointer iter) : m_iter(iter) {}
168 bool operator==(const iterator& other) const
170 return m_iter == other.m_iter;
172 bool operator!=(const iterator& other) const
174 return !operator==(other);
177 iterator operator+(std::size_t i)
181 iterator operator+=(std::size_t i)
185 iterator operator++()
189 iterator operator++(int)
193 const index_type& operator*() const
205 IndexPointer(pointer indices, std::size_t count)
206 : m_indices(indices), m_finish(indices + count) {}
208 iterator begin() const
222 template<typename Element> class BasicVector3;
223 typedef BasicVector3<float> Vector3;
230 virtual void BeginMesh(const Matrix4& localToWorld, bool twoSided = false) = 0;
231 virtual const VolumeTest& getVolume() const = 0;
232 virtual const Vector3& getNear() const = 0;
233 virtual const Vector3& getFar() const = 0;
234 virtual void TestPoint(const Vector3& point, SelectionIntersection& best) = 0;
235 virtual void TestPolygon(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
236 virtual void TestLineLoop(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
237 virtual void TestLineStrip(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
238 virtual void TestLines(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
239 virtual void TestTriangles(const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best) = 0;
240 virtual void TestQuads(const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best) = 0;
241 virtual void TestQuadStrip(const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best) = 0;
249 virtual void pushSelectable(Selectable& selectable) = 0;
250 virtual void popSelectable() = 0;
251 virtual void addIntersection(const SelectionIntersection& intersection) = 0;
254 inline void Selector_add(Selector& selector, Selectable& selectable)
256 selector.pushSelectable(selectable);
257 selector.addIntersection(SelectionIntersection(0, 0));
258 selector.popSelectable();
261 inline void Selector_add(Selector& selector, Selectable& selectable, const SelectionIntersection& intersection)
263 selector.pushSelectable(selectable);
264 selector.addIntersection(intersection);
265 selector.popSelectable();
270 class SelectionTestable
273 STRING_CONSTANT(Name, "SelectionTestable");
275 virtual void testSelect(Selector& selector, SelectionTest& test) = 0;
278 inline SelectionTestable* Instance_getSelectionTestable(scene::Instance& instance)
280 return InstanceTypeCast<SelectionTestable>::cast(instance);
284 template<typename FirstArgument>
287 typedef Callback1<const Plane3&> PlaneCallback;
292 virtual bool contains(const Plane3& plane) const = 0;
295 class PlaneSelectable
298 STRING_CONSTANT(Name, "PlaneSelectable");
300 virtual void selectPlanes(Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback) = 0;
301 virtual void selectReversedPlanes(Selector& selector, const SelectedPlanes& selectedPlanes) = 0;