1 // Copyright (C) 2012-2019 The VPaint Developers.
2 // See the COPYRIGHT file at the top-level directory of this distribution
3 // and at https://github.com/dalboris/vpaint/blob/master/COPYRIGHT
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef PICKING_H
18 #define PICKING_H
19 
20 typedef unsigned int uint;
21 typedef unsigned char uchar;
22 
23 class Picking
24 {
25 public:
26     // ---- Interface for scene objects ----
27 
28     static void glColor(uint id);
29     //
30     // Could be also named setId(uint innerId).
31     //
32     // This  name  reminds  the   user  of  the  underlying  picking
33     // mechanism,  and  then  to remove  all  OpenGL::glColor(color)
34     // calls that would cause the picking to fail.
35     //
36     // A proper  way to do would  be to have a  customized class for
37     // drawing,   like   Drawing::setColor(),   Drawing::drawLine(),
38     // removing  the SceneObject  dependancy to  OpenGL,  and making
39     // possible  to automagically  ignore  Drawing::setColor() calls
40     // when in  picking mode. I  had no time  to do this,  and using
41     // directly OpenGL in SceneObject makes it more flexible.
42     //
43     // Basically, to convert a draw() method into a drawPick():
44     //   - don't draw objects that can't be selected
45     //   - remove all the OpenGL::glColor(color) calls
46     //   - add the Picking::glColor(id) calls
47 
48 
49     // ------   Interface for view/scene ------
50 
51     // set
52     static void setTime(uint time); // for view
53     static void setIndex(uint index);// for scene
54 
55     // get
56     class Object
57     {
58     public:
59         // Constructor: the null object by default
60         Object(uint t=-1, uint i=-1, uint id=-1);
61 
62         // test
63         bool operator==(const Object & other) const;
isNull()64         bool isNull() const { return *this == Object(); }
65 
66         // getter
time()67         uint time() const { return time_; }
index()68         uint index() const { return index_; }
id()69         uint id() const { return id_; }
70 
71     private:
72         uint time_;
73         uint index_;
74         uint id_;
75     };
76     static Object objectFromRGB(uchar r, uchar g, uchar b);
77 
78 
79 private:
80     //
81     // Mapping between RGBA value and picked object:
82     //
83     // rgba_ = RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA
84     //         ^\_________/\_______________/ \_______/
85     //         | index (9)      id (14)       255 (8)
86     //         |
87     //      time (1)
88     //
89     static uint rgba_;
90 };
91 
92 #endif
93