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 ){
38 SelectionIntersection( float depth, float distance ) : m_depth( depth ), m_distance( distance ){
40 bool operator<( const SelectionIntersection& other ) const {
41 if ( m_distance != other.m_distance ) {
42 return m_distance < other.m_distance;
44 if ( m_depth != other.m_depth ) {
45 return m_depth < other.m_depth;
49 bool equalEpsilon( const SelectionIntersection& other, float distanceEpsilon, float depthEpsilon ) const {
50 return float_equal_epsilon( m_distance, other.m_distance, distanceEpsilon )
51 && float_equal_epsilon( m_depth, other.m_depth, depthEpsilon );
61 // returns true if self is closer than other
62 inline bool SelectionIntersection_closer( const SelectionIntersection& self, const SelectionIntersection& other ){
66 // assigns other to best if other is closer than best
67 inline void assign_if_closer( SelectionIntersection& best, const SelectionIntersection& other ){
68 if ( SelectionIntersection_closer( other, best ) ) {
78 typedef const unsigned char* byte_pointer;
80 typedef float elem_type;
81 typedef const elem_type* pointer;
82 typedef const elem_type& reference;
88 iterator( byte_pointer vertices, std::size_t stride )
89 : m_iter( vertices ), m_stride( stride ) {}
91 bool operator==( const iterator& other ) const {
92 return m_iter == other.m_iter;
94 bool operator!=( const iterator& other ) const {
95 return !operator==( other );
98 iterator operator+( std::size_t i ){
99 return iterator( m_iter + i * m_stride, m_stride );
101 iterator operator+=( std::size_t i ){
102 m_iter += i * m_stride;
105 iterator& operator++(){
109 iterator operator++( int ){
110 iterator tmp = *this;
114 reference operator*() const {
115 return *reinterpret_cast<pointer>( m_iter );
119 std::size_t m_stride;
122 VertexPointer( pointer vertices, std::size_t stride )
123 : m_vertices( reinterpret_cast<byte_pointer>( vertices ) ), m_stride( stride ) {}
125 iterator begin() const {
126 return iterator( m_vertices, m_stride );
129 reference operator[]( std::size_t i ) const {
130 return *reinterpret_cast<pointer>( m_vertices + m_stride * i );
134 byte_pointer m_vertices;
135 std::size_t m_stride;
141 typedef unsigned int index_type;
142 typedef const index_type* pointer;
147 iterator( pointer iter ) : m_iter( iter ) {}
149 bool operator==( const iterator& other ) const {
150 return m_iter == other.m_iter;
152 bool operator!=( const iterator& other ) const {
153 return !operator==( other );
156 iterator operator+( std::size_t i ){
159 iterator operator+=( std::size_t i ){
162 iterator operator++(){
165 iterator operator++( int ){
168 const index_type& operator*() const {
178 IndexPointer( pointer indices, std::size_t count )
179 : m_indices( indices ), m_finish( indices + count ) {}
181 iterator begin() const {
184 iterator end() const {
193 template<typename Element> class BasicVector3;
194 typedef BasicVector3<float> Vector3;
201 virtual void BeginMesh( const Matrix4& localToWorld, bool twoSided = false ) = 0;
202 virtual const VolumeTest& getVolume() const = 0;
203 virtual const Vector3& getNear() const = 0;
204 virtual const Vector3& getFar() const = 0;
205 virtual void TestPoint( const Vector3& point, SelectionIntersection& best ) = 0;
206 virtual void TestPolygon( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ) = 0;
207 virtual void TestLineLoop( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ) = 0;
208 virtual void TestLineStrip( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ) = 0;
209 virtual void TestLines( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ) = 0;
210 virtual void TestTriangles( const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best ) = 0;
211 virtual void TestQuads( const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best ) = 0;
212 virtual void TestQuadStrip( const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best ) = 0;
220 virtual void pushSelectable( Selectable& selectable ) = 0;
221 virtual void popSelectable() = 0;
222 virtual void addIntersection( const SelectionIntersection& intersection ) = 0;
225 inline void Selector_add( Selector& selector, Selectable& selectable ){
226 selector.pushSelectable( selectable );
227 selector.addIntersection( SelectionIntersection( 0, 0 ) );
228 selector.popSelectable();
231 inline void Selector_add( Selector& selector, Selectable& selectable, const SelectionIntersection& intersection ){
232 selector.pushSelectable( selectable );
233 selector.addIntersection( intersection );
234 selector.popSelectable();
239 class SelectionTestable
242 STRING_CONSTANT( Name, "SelectionTestable" );
244 virtual void testSelect( Selector& selector, SelectionTest& test ) = 0;
247 inline SelectionTestable* Instance_getSelectionTestable( scene::Instance& instance ){
248 return InstanceTypeCast<SelectionTestable>::cast( instance );
253 typedef Callback1<const Plane3&> PlaneCallback;
258 virtual bool contains( const Plane3& plane ) const = 0;
261 class PlaneSelectable
264 STRING_CONSTANT( Name, "PlaneSelectable" );
266 virtual void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback ) = 0;
267 virtual void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ) = 0;