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 "generic/vector.h"
29 #include "generic/callbackfwd.h"
31 class SelectionIntersection
36 SelectionIntersection() : m_depth(1), m_distance(2)
39 SelectionIntersection(float depth, float distance) : m_depth(depth), m_distance(distance)
42 bool operator<(const SelectionIntersection& other) const
44 if(m_distance != other.m_distance)
46 return m_distance < other.m_distance;
48 if(m_depth != other.m_depth)
50 return m_depth < other.m_depth;
54 bool equalEpsilon(const SelectionIntersection& other, float distanceEpsilon, float depthEpsilon) const
56 return float_equal_epsilon(m_distance, other.m_distance, distanceEpsilon)
57 && float_equal_epsilon(m_depth, other.m_depth, depthEpsilon);
69 // returns true if self is closer than other
70 inline bool SelectionIntersection_closer(const SelectionIntersection& self, const SelectionIntersection& other)
75 // assigns other to best if other is closer than best
76 inline void assign_if_closer(SelectionIntersection& best, const SelectionIntersection& other)
78 if(SelectionIntersection_closer(other, best))
89 typedef const unsigned char* byte_pointer;
91 typedef float elem_type;
92 typedef const elem_type* pointer;
93 typedef const elem_type& reference;
99 iterator(byte_pointer vertices, std::size_t stride)
100 : m_iter(vertices), m_stride(stride) {}
102 bool operator==(const iterator& other) const
104 return m_iter == other.m_iter;
106 bool operator!=(const iterator& other) const
108 return !operator==(other);
111 iterator operator+(std::size_t i)
113 return iterator(m_iter + i * m_stride, m_stride);
115 iterator operator+=(std::size_t i)
117 m_iter += i * m_stride;
120 iterator& operator++()
125 iterator operator++(int)
127 iterator tmp = *this;
131 reference operator*() const
133 return *reinterpret_cast<pointer>(m_iter);
137 std::size_t m_stride;
140 VertexPointer(pointer vertices, std::size_t stride)
141 : m_vertices(reinterpret_cast<byte_pointer>(vertices)), m_stride(stride) {}
143 iterator begin() const
145 return iterator(m_vertices, m_stride);
148 reference operator[](std::size_t i) const
150 return *reinterpret_cast<pointer>(m_vertices + m_stride*i);
154 byte_pointer m_vertices;
155 std::size_t m_stride;
161 typedef unsigned int index_type;
162 typedef const index_type* pointer;
167 iterator(pointer iter) : m_iter(iter) {}
169 bool operator==(const iterator& other) const
171 return m_iter == other.m_iter;
173 bool operator!=(const iterator& other) const
175 return !operator==(other);
178 iterator operator+(std::size_t i)
182 iterator operator+=(std::size_t i)
186 iterator operator++()
190 iterator operator++(int)
194 const index_type& operator*() const
206 IndexPointer(pointer indices, std::size_t count)
207 : m_indices(indices), m_finish(indices + count) {}
209 iterator begin() const
223 template<typename Element> class BasicVector3;
224 typedef BasicVector3<float> Vector3;
231 virtual void BeginMesh(const Matrix4& localToWorld, bool twoSided = false) = 0;
232 virtual const VolumeTest& getVolume() const = 0;
233 virtual const Vector3& getNear() const = 0;
234 virtual const Vector3& getFar() const = 0;
235 virtual void TestPoint(const Vector3& point, SelectionIntersection& best) = 0;
236 virtual void TestPolygon(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
237 virtual void TestLineLoop(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
238 virtual void TestLineStrip(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
239 virtual void TestLines(const VertexPointer& vertices, std::size_t count, SelectionIntersection& best) = 0;
240 virtual void TestTriangles(const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best) = 0;
241 virtual void TestQuads(const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best) = 0;
242 virtual void TestQuadStrip(const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best) = 0;
250 virtual void pushSelectable(Selectable& selectable) = 0;
251 virtual void popSelectable() = 0;
252 virtual void addIntersection(const SelectionIntersection& intersection) = 0;
255 inline void Selector_add(Selector& selector, Selectable& selectable)
257 selector.pushSelectable(selectable);
258 selector.addIntersection(SelectionIntersection(0, 0));
259 selector.popSelectable();
262 inline void Selector_add(Selector& selector, Selectable& selectable, const SelectionIntersection& intersection)
264 selector.pushSelectable(selectable);
265 selector.addIntersection(intersection);
266 selector.popSelectable();
271 class SelectionTestable
274 STRING_CONSTANT(Name, "SelectionTestable");
276 virtual void testSelect(Selector& selector, SelectionTest& test) = 0;
279 inline SelectionTestable* Instance_getSelectionTestable(scene::Instance& instance)
281 return InstanceTypeCast<SelectionTestable>::cast(instance);
286 typedef Callback1<const Plane3&> PlaneCallback;
291 virtual bool contains(const Plane3& plane) const = 0;
294 class PlaneSelectable
297 STRING_CONSTANT(Name, "PlaneSelectable");
299 virtual void selectPlanes(Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback) = 0;
300 virtual void selectReversedPlanes(Selector& selector, const SelectedPlanes& selectedPlanes) = 0;