Salut, alors il y a une erreur que je ne comprends pas, pour un cas ça marche, pour un autre cas, ça ne marche pas.
J'ai d'un côté cette classe-ci :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 #ifndef ODFAEG_SERIALIZATION #define ODFAEG_SERIALIZATION #include <iostream> #include <typeinfo> #include "tuple.h" #include <tuple> namespace odfaeg { template <int N, typename B, typename T, typename A> struct serializer { static void checkType (B* base, T tuple, A & ar) { if (std::get<N>(tuple) != nullptr && typeid(*base) == typeid(*std::get<N>(tuple))) { std::get<N>(tuple)->serialize(ar); } serializer<N-1, B, T, A>::checkType(base, tuple, ar); } }; template <typename B, typename T, typename A> struct serializer <0, B, T, A> { static void checkType (B* base, T tuple, A & ar) { if (std::get<0>(tuple) != nullptr && typeid(*base) == typeid(*std::get<0>(tuple))) { std::get<0>(tuple)->serialize(ar); } else if (base != nullptr) { base->serialize(ar); } } }; template <int N, typename B, typename T> struct sallocator { static B* instanciate (int index, T tuple) { if (N == index) { using D = typename std::remove_pointer<typename std::tuple_element<N, T>::type>::type; return new D(); } sallocator<N-1, B, T>::instanciate(index, tuple); } }; template <typename B, typename T> struct sallocator <0, B, T> { static B* instanciate (int index, T tuple) { using D = typename std::remove_pointer<typename std::tuple_element<0, T>::type>::type; return new D(); } }; template <int N, typename B, typename T> struct sindex { static int getIndex (B* base, T tuple) { if (std::get<N>(tuple) != nullptr && typeid(*base) == typeid(*std::get<N>(tuple))) { return N; } sindex<N-1, B, T>::getIndex(base, tuple); } }; template <typename B, typename T> struct sindex <0, B, T> { static int getIndex (B* base, T tuple) { using D = typename std::remove_pointer<typename std::tuple_element<0, T>::type>::type; D* derived = new D(); if (std::get<0>(tuple) != nullptr && typeid(*base) == typeid(*std::get<0>(tuple))) { return 0; } return -1; } }; template <class B, class... D> class Serializer { public : Serializer() { baseObject = nullptr; } Serializer(B* baseObject) : baseObject(baseObject) { fillTuple(derivedClasses); } void setObject(B* baseObject) { this->baseObject = baseObject; fillTuple(derivedClasses); } template<int... S> void fillTuple(std::tuple<D*...> types) { fillTuple(typename helper::gens<sizeof...(D)>::type(), types); } template<int... S> void fillTuple(helper::seq<S...>, std::tuple<D*...> params) { derivedClasses = std::forward_as_tuple(dynamic_cast<typename std::remove_reference<decltype(std::get<S>(params))>::type> (baseObject)...); } template <typename Archive> void serialize(Archive & ar) { if (std::tuple_size<decltype(derivedClasses)>::value > 0) serializer<std::tuple_size<decltype(derivedClasses)>::value-1, B, decltype(derivedClasses), Archive>::checkType(baseObject, derivedClasses, ar); else baseObject->serialize(ar); } virtual void onSave() { } virtual void onLoad() { } B* sallocate(int index) { if (std::tuple_size<decltype(derivedClasses)>::value > 0) return sallocator<std::tuple_size<decltype(derivedClasses)>::value-1, B, decltype(derivedClasses)>::instanciate(index, derivedClasses); } int getIndex() { if (std::tuple_size<decltype(derivedClasses)>::value > 0) return sindex<std::tuple_size<decltype(derivedClasses)>::value-1, B, decltype(derivedClasses)>::getIndex(baseObject, derivedClasses); return -1; } private : B* baseObject; std::tuple<D*...> derivedClasses; }; } #endif // SERIALIZATION
Avec de l'autre côté celle-ci que j'inclus avec une macro (elle peut être incluse plusieurs fois) :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include "serialisation.h" #define REGISTER_KEY(KEY, TYPE, TYPES...) \ struct KEY : public odfaeg::Serializer<TYPE, TYPES> { \ public : \ KEY () {} \ void register_object (TYPE* object) { \ setObject(object); \ } \ TYPE* allocate_object(int index) { \ return sallocate(index); \ } \ int getTypeIndex () { \ return odfaeg::Serializer<TYPE, TYPES>::getIndex(); \ } \ template <typename Archive> \ void serialize_object (Archive & ar, int) { \ odfaeg::Serializer<TYPE, TYPES>::serialize(ar); \ } \ }; \ public : \ KEY key; \ typedef KEY KEYTYPE; \ static TYPE* allocate (int index) { \ static KEY aKey; \ return aKey.allocate_object(index); \ }
Alors j'inclus le fichier .cpp dans le .h de la classe de base pour générer le code :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 #ifndef ODFAEG_BOUNDING_VOLUME_HPP #define ODFAEG_BOUNDING_VOLUME_HPP #include "../Math/vec4.h" #include <string> #include "../Core/serialization.cpp" #ifndef BVKEY #define BVKEY REGISTER_KEY(BOUNDINGVOLUMEKEY, odfaeg::BoundingVolume, odfaeg::BoundingBox, odfaeg::BoundingSphere) #endif /** *\namespace odfaeg * the namespace of the Opensource Development Framework Adapted for Every Games. */ namespace odfaeg { /** * \file boundingVolume.h * \class BoudingVolume * \brief Manage a bounding volume for collision detection * \author Duroisin.L * \version 1.0 * \date 1/02/2014 * * Base class of all bouding volumes of the framework used for collision detection. * */ class BoundingVolume; class BoundingBox; class BoundingSphere; class BoundingPolyhedron; class BaseInterface { public : void addChild(BoundingVolume* bv) { children.push_back(bv); } std::vector<BoundingVolume*> getChildren() { return children; } std::vector<BoundingVolume*> children; }; template <typename T> class Interface : public BaseInterface { public : T /* const */ & data() /* const*/{return t_;} protected: Interface(T & t) : t_(t){ } const Interface<T>& operator= (const Interface<T>& other) { t_ = other.t_; return *this; } virtual ~Interface(){} private: T & t_; }; class BoundingVolume : public BaseInterface { public : bool intersects(BaseInterface& other) { //if(static_cast<C&>(other)) { if (children.size() == 0 && other.children.size() == 0) { return onIntersects(static_cast<BoundingVolume&>(other)); } else if (children.size() == 0 && other.children.size() != 0) { for (unsigned int i = 0; i < other.children.size(); i++) { if (onIntersects(*static_cast<BoundingVolume&>(other).children[i])) return true; } } else { for (unsigned int i = 0; i < children.size(); i++) { if (other.children.size() == 0) { if (children[i]->onIntersects(static_cast<BoundingVolume&>(other))) return true; } else { for (unsigned j = 0; j < other.children.size(); j++) { if (children[i]->onIntersects(*static_cast<BoundingVolume&>(other).children[j])) return true; } } } } //} return false; } virtual bool onIntersects(BoundingVolume& other) { } virtual Vec3f getPosition() { return Vec3f(0, 0, 0); } virtual Vec3f getSize() { return Vec3f(0, 0, 0); } virtual Vec3f getCenter() { return Vec3f(0, 0, 0); } virtual void move (Vec3f t) { } virtual BoundingVolume* clone () { return new BoundingVolume(*this); } const BoundingVolume& operator= (const BoundingVolume& other) { return *this; } template <typename Archive> void serialize(Archive & ar) { std::cout<<"Serialize bounding volume"<<std::endl; } virtual ~BoundingVolume() {} BVKEY }; } #endif // BOUNDING_AREAS
Ceci me génère du code à l'aide de la macro dans le .h de la classe de base lorsque j'inclus le .h de la classe de base. (Jusque là pas de problèmes)
J'ai une classe dérivée BoundingBox (jusque là pas de problème non plus, voici la classe :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 #ifndef ODFAEG_BOUNDING_BOX_HPP #define ODFAEG_BOUNDING_BOX_HPP #include "../Math/vec2f.h" #include "ray.h" #include "boundingVolume.h" /** *\namespace odfaeg * the namespace of the Opensource Development Framework Adapted for Every Games. */ namespace odfaeg { class BoundingSphere; class BoundingEllipsoid; class OrientedBoundingBox; class BoundingPolyhedron; /** * \file boundingBox.h * \class BoudingBox * \brief Manage a bounding box for collision detection * \author Duroisin.L * \version 1.0 * \date 1/02/2014 * * Manage a bounding box for collision detection. * The bounding box is aligned with the x and y axis. * */ class BoundingBox : public BoundingVolume, public Interface<BoundingBox> { public : /** \fn BoundingBox() * \brief Default constructor (initialize a bounding retangle at position (0, 0) and with a size of (0, 0). */ BoundingBox (); /** \fn BoundingBox (int, int, int, int int, int) * \brief Initialize a bounding box with the given position and the given size * \param the x position of the bounding box * \param the y position of the bounding box * \param the z position of the bounding box * \param the width of the bounding box * \param the height of the bounding box * \param the depth of the bounding box */ BoundingBox (int x, int y, int z, int width, int height, int depth); /** \fn bool intersects (BoundingSphere &bs) * \brief test if a bounding sphere collides with the bounding sphere. * \param the bounding sphere to test with. * \return the result of the collision test. */ bool onIntersects (BoundingVolume& interface); bool intersects (BoundingSphere &bs); /** \fn bool intersects (BoundingEllipsoid &be) * \brief test if a bounding ellipsoid collides with the bounding box. * \param the bounding ellipsoid to test with. * \return the result of the collision test. */ bool intersects (BoundingEllipsoid &bc); /** \fn bool intersects (BoundingBox &br) * \brief test if an other bounding box collides with the bounding box. * \param the other bounding box to test with. * \return the result of the collision test. */ bool intersects (BoundingBox &bx); /** \fn bool intersects (OrientedBoundingBox &br) * \brief test if an oriented bounding sphere collides with the bounding box. * \param the oriented bounding box to test with. * \return the result of the collision test. */ bool intersects (OrientedBoundingBox &obx); /** \fn bool intersects (BoundingPolyhedron &bp) * \brief test if a bounding polyhedron collides with the bounding box. * \param the bounding polyhedron to test with. * \return the result of the collision test. */ bool intersects (BoundingPolyhedron &bp); /** \fn bool intersects (Ray &ray) * \brief test if a ray collides with the bounding box. * \param the Segment to test with. * \return the result of the collision test. */ bool intersects (Ray& ray); /** \fn bool isPointInside (Vec2f point) * \brief test if a point is in the bounding box. * \param the point to test in. * \return the result of the collision test. */ bool isPointInside (Vec3f point); /**\fn Vec2f getCenter() * \brief gives the center of the bounding box. * \return the center of the bounding box. */ Vec3f getCenter(); /**\fn float getWidth() * \brief gives the width of the bounding box. * \return the width of the bounding box. */ float getWidth(); /**\fn float getHeight() * \brief gives the height of the bounding box. * \return the height of the bounding box. */ float getHeight(); /**\fn float getDepth() * \brief gives the depth of the bounding box. * \return the depth of the bounding box. */ float getDepth(); /**\fn Vec3f getPosition() * \brief gives the position of the bounding box. * \return the position of the bounding box. */ Vec3f getSize(); Vec3f getPosition(); /**\fn void setPosition(int x, int y, int z) * \brief set the position of the bounding box. * \param the x position of the bounding box. * \param the y position of the bounding box. */ void setPosition(int x, int y, int z); /**\fn void setSize(int width, int height, int depth) * \brief set the size of the bounding box. * \param the width of the bounding box. * \param the height of the bounding box. * \param the depth of the bounding box. */ void setSize(int width, int height, int depth); void move (Vec3f t); std::string getType() { return "BoundingBox"; } const BoundingBox& operator= (const BoundingBox& other) { x = other.x; y = other.y; z = other.z; width = other.width; height = other.height; depth = other.depth; vertices = other.vertices; return *this; } template <typename Archive> void serialize(Archive & ar) { BoundingVolume::serialize(ar); std::cout<<"serialize bounding box"<<std::endl; ar(x); ar(y); ar(z); ar(width); ar(height); ar(depth); ar(center); } private : std::array<Vec3f, 8> vertices; int x, y, z, width, height, depth; /**< the x position of the bounding box */ /**< the y position of the bounding box */ /**< the z position of the bounding box */ /**< the width of the bounding box */ /**< the height of the bounding box */ /**< the depth of the bounding box */ Vec3f center; /**< the center of the bounding box */ }; } #endif
Et l'inplémentation :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258 #include "../../../include/odfaeg/Physics/boundingBox.h" #include "../../../include/odfaeg/Physics/boundingSphere.h" #include "../../../include/odfaeg/Physics/boundingEllipsoid.h" #include "../../../include/odfaeg/Physics/orientedBoundingBox.h" #include "../../../include/odfaeg/Physics/boundingPolyhedron.h" using namespace std; namespace odfaeg { //Create a bounding box at position 0, 0, 0 and with the dimensions 1, 1, 1. BoundingBox::BoundingBox() : Interface<BoundingBox>(*this) { int x = y = z = 0; width = height = depth = 1; vertices[0] = Vec3f(x, y, z); vertices[1] = Vec3f(x + width, y, z); vertices[2] = Vec3f(x + width, y + height, z); vertices[3] = Vec3f(x, y + height, z); vertices[4] = Vec3f(x, y, z + depth); vertices[5] = Vec3f(x + width, y, z + depth); vertices[6] = Vec3f(x + width, y + height, z + depth); vertices[7] = Vec3f(x, y + height, z + depth); } //Create a bounding box with the specified , y, z position and of width, height, depth dimensions. BoundingBox::BoundingBox (int x, int y, int z, int width, int height, int depth) : Interface<BoundingBox>(*this), center (x + width * 0.5f, y + height * 0.5f, z + depth * 0.5f) { this->x = x; this->y = y; this->z = z; this->width = width; this->height = height; this->depth = depth; vertices[0] = Vec3f(x, y, z); vertices[1] = Vec3f(x + width, y, z); vertices[2] = Vec3f(x + width, y + height, z); vertices[3] = Vec3f(x, y + height, z); vertices[4] = Vec3f(x, y, z + depth); vertices[5] = Vec3f(x + width, y, z + depth); vertices[6] = Vec3f(x + width, y + height, z + depth); vertices[7] = Vec3f(x, y + height, z + depth); } bool BoundingBox::onIntersects (BoundingVolume& interface) { return intersects(static_cast<BoundingBox&>(interface)); } //Test if the box intersects the specified sphere. bool BoundingBox::intersects (BoundingSphere &bs) { return bs.intersects(*this); } //Test if the box intersects the specified ellipsoid. bool BoundingBox::intersects (BoundingEllipsoid &be) { return be.intersects(*this); } //Test if the box intersects another. bool BoundingBox::intersects (BoundingBox &other) { //Get the medians of our two boxes. /*Vec3f hi1[6]; hi1[0] = Vec3f(width * 0.5f, 0, 0); hi1[1] = Vec3f(0, height * 0.5f, 0); hi1[2] = Vec3f(0, 0, depth * 0.5f); hi1[3] = Vec3f(-width * 0.5f, 0, 0); hi1[4] = Vec3f(0, -height * 0.5f, 0); hi1[5] = Vec3f(0, 0, -depth * 0.5f); Vec3f hi2[6]; hi2[0] = Vec3f(other.width * 0.5f, 0, 0); hi2[1] = Vec3f(0, other.height * 0.5f, 0); hi2[2] = Vec3f(0, 0, other.depth * 0.5f); hi1[3] = Vec3f(-width * 0.5f, 0, 0); hi1[4] = Vec3f(0, -height * 0.5f, 0); hi1[5] = Vec3f(0, 0, -depth * 0.5f); for (unsigned int i = 0; i < 6; i++) { Vec2f p1 = Computer::projectShapeOnAxis(hi1[i], vertices); Vec2f p2 = Computer::projectShapeOnAxis(hi1[i], other.vertices); if (!Computer::overlap(p1, p2)) return false; } for (unsigned int i = 0; i < 6; i++) { Vec2f p1 = Computer::projectShapeOnAxis(hi2[i], vertices); Vec2f p2 = Computer::projectShapeOnAxis(hi2[i], other.vertices); if (!Computer::overlap(p1, p2)) return false; } return true;*/ //std::cout<<"other : "<<&other<<std::endl; int hx1 = width * 0.5; int hy1 = height * 0.5; int hz1 = depth * 0.5; int hx2 = other.width * 0.5; int hy2 = other.height * 0.5; int hz2 = other.depth * 0.5; //Check the mins and max medians positions. float minX1 = center.x - hx1, minX2 = other.center.x - hx2; float minY1 = center.y - hy1, minY2 = other.center.y - hy2; float minZ1 = center.z - hz1, minZ2 = other.center.z - hz2; float maxX1 = center.x + hx1, maxX2 = other.center.x + hx2; float maxY1 = center.y + hy1, maxY2 = other.center.y + hy2; float maxZ1 = center.z + hz1, maxZ2 = other.center.z + hz2; //If the medians overlap, our two boxes intersects. for (int i = 0; i < 3; i++) { if (i == 0) { if (minX1 > maxX2 || maxX1 < minX2) return false; } else if (i == 1) { if (minY1 > maxY2 || maxY1 < minY2) return false; } else { if (minZ1 > maxZ2 || maxZ1 < minZ2) return false; } } return true; /*Vec3f d = other.center - center; int c = d.magnitude() * 2; Vec3f hi[3]; hi[0] = Vec3f(width * 0.5f, 0, 0); hi[1] = Vec3f(0, height * 0.5f, 0); hi[2] = Vec3f(0, 0, depth * 0.5f); Vec3f hi2[3]; hi2[0] = Vec3f(other.width * 0.5f, 0, 0); hi2[1] = Vec3f(0, other.height * 0.5f, 0); hi2[2] = Vec3f(0, 0, other.depth * 0.5f); for (unsigned int i = 0; i < 3; i++) { int r1 = hi[i].projOnVector(d).magnitude(); int r2; for (unsigned int j = 0; j < 3; j++) { r2 = hi2[j].projOnVector(d).magnitude(); } int rSum = r1 + r2; std::cout<<rSum<<" "<<c<<std::endl; if (c - rSum > 0) return false; } return true;*/ } //Test if an the box intersects with the specified oriented bounding box. bool BoundingBox::intersects(OrientedBoundingBox &obx) { return obx.intersects(*this); } //Test if the bounding box intersects with the specified bounding polyhedron. bool BoundingBox::intersects (BoundingPolyhedron &bp) { Vec3f hi[6]; hi[0] = Vec3f(width * 0.5f, 0, 0); hi[1] = Vec3f(0, height * 0.5f, 0); hi[2] = Vec3f(0, 0, depth * 0.5f); hi[3] = Vec3f(-width * 0.5f, 0, 0); hi[4] = Vec3f(0, -height * 0.5f, 0); hi[5] = Vec3f(0, 0, -depth * 0.5f); std::vector<Vec3f> normals = bp.getNormals(); for (unsigned int i = 0; i < 6; i++) { Vec2f p1 = Computer::projectShapeOnAxis(hi[i], bp.getPoints()); Vec2f p2 = Computer::projectShapeOnAxis(hi[i], vertices); if (!Computer::overlap(p1, p2)) return false; } for (unsigned int i = 0; i < normals.size(); i++) { Vec2f p1 = Computer::projectShapeOnAxis(normals[i], bp.getPoints()); Vec2f p2 = Computer::projectShapeOnAxis(normals[i], vertices); if (!Computer::overlap(p1, p2)) return false; } return true; } //Test if a point is inside our box. bool BoundingBox::isPointInside (Vec3f point) { //Check the min and max values of the medians of our box. float minX = center.x - width * 0.5f; float maxX = center.x + width * 0.5f; float minY = center.y - height * 0.5f; float maxY = center.y + height * 0.5f; float minZ = center.z - depth * 0.5f; float maxZ = center.z + depth * 0.5f; //If one of the point is on one of the x, y or z medians, the point is inside the box. return (point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY && point.z >= minZ && point.z <= maxZ); } bool BoundingBox::intersects (Ray &ray) { float tFar = INT_MAX; float tNear = -INT_MAX; for (int i = 0; i < 3; i++) { float d, orig, hi; if (i == 0) { hi = width / 2; d = ray.getDir().x; orig = ray.getOrig().x - center.x; } else if (i == 1) { hi = height / 2; d = ray.getDir().y; orig = ray.getOrig().y - center.y; } else { hi = depth / 2; d = ray.getDir().z; orig = ray.getOrig().z - center.z; } if (d == 0) if (Math::abs(orig) > hi) return false; float t1 = (-hi - orig) / d; float t2 = (hi - orig) / d; float tmp; if (t1 > t2) { tmp = t1; t1 = t2; t2 = tmp; } else tmp = t1; if (t1 > tNear) tNear = t1; if (t2 < tFar) tFar = t2; if (tNear > tFar) return false; if(tFar < 0) return false; } return true; } //Acceseurs. Vec3f BoundingBox::getCenter () { return center; } float BoundingBox::getWidth () { return width; } float BoundingBox::getHeight () { return height; } float BoundingBox::getDepth() { return depth; } Vec3f BoundingBox::getSize() { return Vec3f(width, height, depth); } Vec3f BoundingBox::getPosition () { return Vec3f (x, y, z); } void BoundingBox::setPosition(int x, int y, int z) { this->x = x; this->y = y; this->z = z; } void BoundingBox::setSize(int width, int height, int depth) { this->width = width; this->height = height; this->depth = depth; } void BoundingBox::move(Vec3f t) { for (unsigned int i = 0; i < vertices.size(); i++) vertices[i] += t; x = vertices[0].x; y = vertices[0].y; z = vertices[0].z; center.x = x + width * 0.5f; center.y = y + height * 0.5f; center.z = z + depth * 0.5f; } }
Le problème survient avec cette classe (lorsque je déclare cette classe dans la macro) :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 #ifndef ODFAEG_BOUNDING_SPHERE_HPP #define ODFAEG_BOUNDING_SPHERE_HPP #include "../Math/vec2f.h" #include "ray.h" #include "boundingVolume.h" /** *\namespace odfaeg * the namespace of the Opensource Development Framework Adapted for Every Games. */ namespace odfaeg { /** * \file boundingSphere.h * \class BoudingSphere * \brief Manage a bounding sphere for collision detection * \author Duroisin.L * \version 1.0 * \date 1/02/2014 * * Manage a bounding sphere for collision detection. * */ class BoundingEllipsoid; class OrientedBoundingBox; class BoundingPolyhedron; class BoundingBox; class BoundingSphere : public BoundingVolume, public Interface<BoundingSphere> { public : BoundingSphere(); /** * \fn BoundingSphere (Vec2f center, float radius) * \brief Constructor : create an instance of a bounding sphere. * \param the center of the bounding sphere. * \param the radius of the bounding sphere. */ BoundingSphere (Vec3f center, float radius); /**\fn bool intersects (BoundingSphere &other) * \brief check if the bounding sphere is in collision with an other. * \param the other bounding sphere to test with. * \return the result of the collision test. */ bool onIntersects (BoundingVolume& interface); bool intersects (BoundingSphere &other); /** \fn bool intersects (BoundingEllipsoid &be) * \brief check if the bounding sphere is in collision with a bounding ellipsoid. * \param the bouding ellipsoid to test with. * \return the result of the collision test. */ bool intersects (BoundingEllipsoid &be); /** \fn bool intersects (BoundingBox &br) * \brief check if the bounding sphere is in collision with a bounding box. * \param the bounding box to test with. * \return the result of the collision test. */ bool intersects (BoundingBox &obr); /**\fn bool intersects (OrientedBoundingRectangle &obr) * \brief check if the bounding sphere is in collision with an oriented bounding box. * \param the oriented bounding box to test with. * \return the result of the collision test. */ bool intersects (OrientedBoundingBox &obr); /**\fn bool intersects (BoundingPolygon &bp) * \brief check if the bounding sphere is in collision with a bounding polyhedron. * \param the bounding polyhedron to test with. * \return the result of the collision test. */ bool intersects (BoundingPolyhedron &bp); /** \fn bool isPointInside (Vec2f &point) * \brief check if a point is inside the sphere. * \param the point to test in. * \return the result of the collision test. */ bool isPointInside (Vec3f &point); /** \fn bool intersects (Segment &ray) * \brief check if a ray interects the sphere. * \param the ray to test with. * \return the result of the collision test. */ bool intersects (Ray& ray); /** \fn bool intersects (Segment &ray, Vec2f &near, Vec2f &far) * \brief check if a ray interects the sphere and get the points of the intersection. * \param the ray to test with. * \param the vector to store the nearest point of the intersection. (from the ray's origin) * \param the vector to store the farest point of the intersection. (from the ray"s origin) * \return the result of the collision test. */ bool intersectsWhere (Ray &ray, Vec3f &near, Vec3f &far); /** \fn Vec2f getCenter() * \return the center of the bounding sphere. */ Vec3f getPosition(); Vec3f getCenter(); /** \fn Vec2f getRadius() * \return the radius of the bounding sphere. */ Vec3f getSize(); float getRadius(); template <typename Archive> void serialize (Archive & ar) { BoundingVolume::serialize(ar); std::cout<<"Serialize bounding sphere"<<std::endl; ar(center); ar(radius); } void move(Vec3f t); const BoundingSphere& operator= (const BoundingSphere& other) { *this = other; return *this; } private : Vec3f center; /** < the center of the bouding sphere */ float radius; /** < the radius of the bouding sphere */ }; } #endif
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 #include "../../../include/odfaeg/Physics/boundingSphere.h" #include "../../../include/odfaeg/Physics/boundingEllipsoid.h" #include "../../../include/odfaeg/Physics/boundingBox.h" #include "../../../include/odfaeg/Physics/orientedBoundingBox.h" #include "../../../include/odfaeg/Physics/boundingPolyhedron.h" using namespace std; namespace odfaeg { /*Crée un cercle englobant, utilisé pour les détection de collisions, et la sélection * d'objets. */ //Crée un cercle de centre center et de rayon radius. BoundingSphere::BoundingSphere() : Interface<BoundingSphere>(*this) {} BoundingSphere::BoundingSphere (Vec3f center, float radius) : Interface<BoundingSphere>(*this) { this->center = center; this->radius = radius; } bool BoundingSphere::onIntersects (BoundingVolume& interface) { return intersects(static_cast<BoundingSphere&>(interface)); } bool BoundingSphere::intersects (BoundingSphere &other) { float d = center.computeDist (other.center); float rSum = radius + other.radius; return (d <= rSum); } bool BoundingSphere::intersects (BoundingEllipsoid &be) { return be.intersects(*this); } bool BoundingSphere::intersects (BoundingBox &bx) { Vec3f d = bx.getCenter() - center; float m = center.computeDist(bx.getCenter()); Vec3f near, far; Ray r (bx.getCenter(), center); intersectsWhere(r, near, far); Vec3f d2 = near - center; int ray2 = d2.projOnAxis(d); float hi[3]; hi[0] = bx.getWidth() * 0.5f; hi[1] = bx.getHeight() * 0.5f; hi[2] = bx.getHeight() * 0.5f; for (int i = 0; i < 3; i++) { int rSum = radius + hi[i]; if (m - rSum > 0.f) return false; } return true; } bool BoundingSphere::intersects (OrientedBoundingBox &obx) { Vec3f d = obx.getCenter() - center; float m = center.computeDist(obx.getCenter()); Vec3f near, far; Ray r(obx.getCenter(), center); intersectsWhere(r, near, far); Vec3f d2 = near - center; int ray2 = d2.projOnAxis(d); Vec3f bi[3]; bi[0] = obx.getBX() * obx.getWidth() * 0.5f; bi[1] = obx.getBY() * obx.getHeight() * 0.5f; bi[2] = obx.getBZ() * obx.getDepth() * 0.5f; for (int i = 0; i < 3; i++) { float ray2 = bi[i].projOnAxis(d); int rSum = radius + ray2; if (m - rSum > 0.f) return true; } return false; } bool BoundingSphere::intersects (BoundingPolyhedron &bp) { Vec3f d = bp.getCenter() - center; float m = center.computeDist(bp.getCenter()); Vec3f near, far; Ray r(bp.getCenter(), center); intersectsWhere(r, near, far); Vec3f d2 = near - center; int ray2 = d2.projOnAxis(d); Vec3f a = bp.getPoint(0); Vec3f b = bp.getPoint(1); Vec3f mid = a + (b - a) * 0.5f; Vec3f bi = mid - bp.getCenter(); float proj = bi.projOnAxis(d); int min = proj; int max = proj; for (unsigned int j = 1; j < bp.nbPoints(); j++) { a = bp.getPoint(j); if (j != bp.nbPoints() - 1) b = bp.getPoint(j+1); else b = bp.getPoint(0); mid = a + (b - a) * 0.5f; bi = (mid - bp.getCenter()) * 0.5f; proj = bi.projOnAxis(d); if (proj < min) min = proj; if (proj > max) max = proj; } ray2 = max - min; int rSum = radius + ray2; if (m - rSum > 0.f) return true; return false; } bool BoundingSphere::intersects (Ray &ray) { float c = radius; Vec3f d1 = ray.getExt() - center; Vec3f d2 = ray.getOrig() - center; Vec3f b = (ray.getOrig() + ray.getExt()) * 0.5f - center; Vec3f norm (ray.getOrig().y - ray.getExt().y, ray.getExt().x - ray.getOrig().x, ray.getExt().z - ray.getOrig().z); if (b.dot2(norm) < 0) norm = -norm; Vec3f n = b.projOnVector(norm); float r1 = d1.projOnAxis(n); float r2 = d2.projOnAxis(n); if (r1 - c > 0 && r2 - c > 0) return false; return true; } bool BoundingSphere::intersectsWhere (Ray& r, Vec3f& near, Vec3f &far) { Vec3f d = r.getOrig() - center; float a = r.getDir().dot(r.getDir()); float b = 2 * r.getDir().dot(d); float c = d.dot(d) - (radius * radius); float disc = b * b - 4 * a * c; if (disc < 0) return false; float distSqrt = Math::sqrt(disc); float q; if (b < 0) q = (-b - distSqrt)/2.0; else q = (-b + distSqrt)/2.0; // compute t0 and t1 float t0 = q / a; float t1 = c / q; // make sure t0 is smaller than t1 if (t0 > t1) { // if t0 is bigger than t1 swap them around float temp = t0; t0 = t1; t1 = temp; } // if t1 is less than zero, the object is in the ray's negative direction // and consequently the ray misses the sphere if (t1 < 0) return false; // if t0 is less than zero, the intersection point is at t1 bool intersects = false; if (t0 < 0) { near = r.getOrig() + r.getDir() * t1; intersects = true; } // else the intersection point is at t0 else { far = r.getOrig() + r.getDir() * t0; if (!intersects) intersects = true; } return intersects; } //Test si un point est à l'intérieur du cercle. bool BoundingSphere::isPointInside (Vec3f &point) { float d = center.computeDist(point); return d < radius; } Vec3f BoundingSphere::getPosition() { return Vec3f(center.x - radius, center.y - radius, center.z - radius); } Vec3f BoundingSphere::getCenter() { return center; } Vec3f BoundingSphere::getSize() { return Vec3f(radius * 2, radius * 2, radius * 2); } float BoundingSphere::getRadius () { return radius; } void BoundingSphere::move(Vec3f t) { } }
Là, le compilateur ne compile plus et me renvoie...., cette erreur!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 -------------- Build: Debug in ODFAEG (compiler: GNU GCC Compiler)--------------- g++-4.8 -Os -O3 -std=c++11 -pg -Wall -pg -g -I../../../../../usr/local/include/SFML -I../../../../../usr/include/openssl -I../../../../../usr/include/freetype2 -c /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp -o obj/Debug/src/odfaeg/Graphics/projMatrix.o In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingBox.h:5:0, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/projMatrix.h:8, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp:1: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingVolume.h: In member function virtual bool odfaeg::BoundingVolume::onIntersects(odfaeg::BoundingVolume&): /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingVolume.h:85:5: warning: no return statement in function returning non-void [-Wreturn-type] } ^ In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/vec4.h:8:0, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/matrix4.h:3, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/projMatrix.h:4, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp:1: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h: In instantiation of static B* odfaeg::sallocator<N, B, T>::instanciate(int, T) [with int N = 1; B = odfaeg::BoundingVolume; T = std::tuple<odfaeg::BoundingBox*, odfaeg::BoundingSphere*>]: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:100:146: required from B* odfaeg::Serializer<B, D>::sallocate(int) [with B = odfaeg::BoundingVolume; D = {odfaeg::BoundingBox, odfaeg::BoundingSphere}] /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingVolume.h:108:5: required from here /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:33:26: error: invalid use of incomplete type using D = std::__remove_pointer_helper<odfaeg::BoundingSphere*, odfaeg::BoundingSphere*>::type {aka class odfaeg::BoundingSphere} return new D(); ^ In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingBox.h:5:0, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/projMatrix.h:8, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp:1: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingVolume.h:27:7: error: forward declaration of using D = std::__remove_pointer_helper<odfaeg::BoundingSphere*, odfaeg::BoundingSphere*>::type {aka class odfaeg::BoundingSphere} class BoundingSphere; ^ In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/vec4.h:8:0, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/matrix4.h:3, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/projMatrix.h:4, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp:1: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h: In instantiation of static int odfaeg::sindex<N, B, T>::getIndex(B*, T) [with int N = 1; B = odfaeg::BoundingVolume; T = std::tuple<odfaeg::BoundingBox*, odfaeg::BoundingSphere*>]: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:105:144: required from int odfaeg::Serializer<B, D>::getIndex() [with B = odfaeg::BoundingVolume; D = {odfaeg::BoundingBox, odfaeg::BoundingSphere}] /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingVolume.h:108:5: required from here /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:48:60: error: invalid use of incomplete type class odfaeg::BoundingSphere if (std::get<N>(tuple) != nullptr && typeid(*base) == typeid(*std::get<N>(tuple))) { ^ In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingBox.h:5:0, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/projMatrix.h:8, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp:1: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingVolume.h:27:7: error: forward declaration of class odfaeg::BoundingSphere class BoundingSphere; ^ In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/vec4.h:8:0, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/matrix4.h:3, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/projMatrix.h:4, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp:1: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h: In instantiation of void odfaeg::Serializer<B, D>::fillTuple(odfaeg::helper::seq<S ...>, std::tuple<D* ...>) [with int ...S = 0, 1; B = odfaeg::BoundingVolume; D = {odfaeg::BoundingBox, odfaeg::BoundingSphere}]: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:81:69: required from void odfaeg::Serializer<B, D>::fillTuple(std::tuple<D* ...>) [with int ...S = {}; B = odfaeg::BoundingVolume; D = {odfaeg::BoundingBox, odfaeg::BoundingSphere}] /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:77:33: required from void odfaeg::Serializer<B, D>::setObject(B*) [with B = odfaeg::BoundingVolume; D = {odfaeg::BoundingBox, odfaeg::BoundingSphere}] /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Physics/boundingVolume.h:108:5: required from here /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:85:146: error: cannot dynamic_cast ((odfaeg::Serializer<odfaeg::BoundingVolume, odfaeg::BoundingBox, odfaeg::BoundingSphere>*)this)->odfaeg::Serializer<odfaeg::BoundingVolume, odfaeg::BoundingBox, odfaeg::BoundingSphere>::baseObject (of type class odfaeg::BoundingVolume*) to type std::remove_reference<odfaeg::BoundingSphere*&>::type {aka class odfaeg::BoundingSphere*} (target is not pointer or reference to complete type) derivedClasses = std::forward_as_tuple(dynamic_cast<typename std::remove_reference<decltype(std::get<S>(params))>::type> (baseObject)...); ^ In file included from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/vec4.h:8:0, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/matrix4.h:3, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/projMatrix.h:4, from /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/projMatrix.cpp:1: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h: In static member function static B* odfaeg::sallocator<N, B, T>::instanciate(int, T) [with int N = 1; B = odfaeg::BoundingVolume; T = std::tuple<odfaeg::BoundingBox*, odfaeg::BoundingSphere*>]: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:36:5: warning: control reaches end of non-void function [-Wreturn-type] } ^ /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h: In static member function static int odfaeg::sindex<N, B, T>::getIndex(B*, T) [with int N = 1; B = odfaeg::BoundingVolume; T = std::tuple<odfaeg::BoundingBox*, odfaeg::BoundingSphere*>]: /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Graphics/../../../include/odfaeg/Graphics/../Math/../Core/serialization.h:52:5: warning: control reaches end of non-void function [-Wreturn-type] } ^ Process terminated with status 1 (0 minute(s), 2 second(s)) 5 error(s), 13 warning(s) (0 minute(s), 2 second(s))
Partager