PrimitiveFilter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package VisionX
19 * @author Markus Grotz ( markus dot grotz at kit dot edu )
20 * @date 2015
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "PrimitiveFilter.h"
26
28
29
30using namespace armarx;
31
35
39
40void
42 std::vector<memoryx::EnvironmentalPrimitiveBasePtr> allPrimitives,
43 std::vector<memoryx::EnvironmentalPrimitiveBasePtr>& visibilePrimitives,
44 std::vector<memoryx::EnvironmentalPrimitiveBasePtr>& otherPrimitives)
45{
46 for (memoryx::EnvironmentalPrimitiveBasePtr& p : allPrimitives)
47 {
48 if (!p->getPose())
49 {
50 ARMARX_WARNING << "no pose for primitive " << p->getId();
51 continue;
52 }
53
54 Eigen::Matrix4f pose = FramedPosePtr::dynamicCast(p->getPose())->toEigen();
55
56 Eigen::Vector3f OBBDimensions = Vector3Ptr::dynamicCast(p->getOBBDimensions())->toEigen();
57
58 if (intersectsFrustum(pose, OBBDimensions))
59 {
60 visibilePrimitives.push_back(p);
61 }
62 else
63 {
64 otherPrimitives.push_back(p);
65 }
66 }
67}
68
69void
71{
72
73 Eigen::Vector3f nearTopRight = frustum.col(0);
74 Eigen::Vector3f nearTopLeft = frustum.col(1);
75 Eigen::Vector3f farTopLeft = frustum.col(2);
76 Eigen::Vector3f nearBottomLeft = frustum.col(3);
77 Eigen::Vector3f nearBottomRight = frustum.col(4);
78 Eigen::Vector3f farBottomRight = frustum.col(5);
79 Eigen::Vector3f farTopRight = frustum.col(15);
80 Eigen::Vector3f farBottomLeft = frustum.col(17);
81
82 Vector3BasePtr start = new Vector3(nearTopLeft);
83 Vector3BasePtr stop = new Vector3(nearBottomLeft);
84 DrawColor color;
85 debugDrawerTopicPrx->setLineVisu("primitiveMapper", "frustumNearLeft", start, stop, 1.0, color);
86
87 start = new Vector3(farTopLeft);
88 stop = new Vector3(farBottomLeft);
89 debugDrawerTopicPrx->setLineVisu("primitiveMapper", "frustumFarLeft", start, stop, 1.0, color);
90
91 start = new Vector3(nearTopRight);
92 stop = new Vector3(nearBottomRight);
93 debugDrawerTopicPrx->setLineVisu(
94 "primitiveMapper", "frustumNearRight", start, stop, 1.0, color);
95
96 start = new Vector3(farTopRight);
97 stop = new Vector3(farBottomRight);
98 debugDrawerTopicPrx->setLineVisu("primitiveMapper", "frustumFarRight", start, stop, 1.0, color);
99
100 start = new Vector3(nearBottomLeft);
101 stop = new Vector3(nearBottomRight);
102 debugDrawerTopicPrx->setLineVisu(
103 "primitiveMapper", "frustumNearBottom", start, stop, 1.0, color);
104
105 start = new Vector3(farBottomLeft);
106 stop = new Vector3(farBottomRight);
107 debugDrawerTopicPrx->setLineVisu(
108 "primitiveMapper", "frustumFarBottom", start, stop, 1.0, color);
109
110 start = new Vector3(nearBottomRight);
111 stop = new Vector3(farBottomRight);
112 debugDrawerTopicPrx->setLineVisu(
113 "primitiveMapper", "frustumRightBottom", start, stop, 1.0, color);
114
115 start = new Vector3(nearBottomLeft);
116 stop = new Vector3(farBottomLeft);
117 debugDrawerTopicPrx->setLineVisu(
118 "primitiveMapper", "frustumLeftBottom", start, stop, 1.0, color);
119
120 start = new Vector3(nearTopRight);
121 stop = new Vector3(farTopRight);
122 debugDrawerTopicPrx->setLineVisu("primitiveMapper", "frustumRightTop", start, stop, 1.0, color);
123
124 start = new Vector3(nearTopLeft);
125 stop = new Vector3(farTopLeft);
126 debugDrawerTopicPrx->setLineVisu("primitiveMapper", "frustumLeftTop", start, stop, 1.0, color);
127}
128
129/**
130 * adapted from
131 * https://github.com/vanderlin/FrustumCulling/
132 */
133Eigen::Matrix3Xf
134PrimitiveFilter::updateCameraPosition(Eigen::Matrix4f cameraToWorld)
135{
136 float imageSizeRatio = 640.0 / 480.0;
137
138 float farClipDistance = 3000.0;
139 float nearClipDistance = 400.0;
140
141 Eigen::Vector3f farCenter(0, 0, farClipDistance);
142 Eigen::Vector3f nearCenter(0, 0, nearClipDistance);
143
144 float a = -1.0 * std::tan(0.3926990925);
145
146 Eigen::Vector3f farVertical(0, a * farClipDistance, 0);
147 Eigen::Vector3f farHorizontal(a * farClipDistance * imageSizeRatio, 0, 0);
148
149 Eigen::Vector3f farTopLeft = farCenter - farVertical - farHorizontal;
150 Eigen::Vector3f farTopRight = farCenter - farVertical + farHorizontal;
151
152 Eigen::Vector3f farBottomLeft = farCenter + farVertical - farHorizontal;
153 Eigen::Vector3f farBottomRight = farCenter + farVertical + farHorizontal;
154
155 Eigen::Vector3f nearVertical(0, a * nearClipDistance, 0);
156 Eigen::Vector3f nearHorizontal(a * nearClipDistance * imageSizeRatio, 0, 0);
157
158 Eigen::Vector3f nearTopLeft = nearCenter - nearVertical - nearHorizontal;
159 Eigen::Vector3f nearTopRight = nearCenter - nearVertical + nearHorizontal;
160
161 Eigen::Vector3f nearBottomLeft = nearCenter + nearVertical - nearHorizontal;
162 Eigen::Vector3f nearBottomRight = nearCenter + nearVertical + nearHorizontal;
163
164
165 frustum.col(0) = nearTopRight;
166 frustum.col(1) = nearTopLeft;
167 frustum.col(2) = farTopLeft;
168
169 frustum.col(3) = nearBottomLeft;
170 frustum.col(4) = nearBottomRight;
171 frustum.col(5) = farBottomRight;
172
173 frustum.col(6) = nearTopLeft;
174 frustum.col(7) = nearBottomLeft;
175 frustum.col(8) = farBottomLeft;
176
177 frustum.col(9) = nearBottomRight;
178 frustum.col(10) = nearTopRight;
179 frustum.col(11) = farBottomRight;
180
181 frustum.col(12) = nearTopLeft;
182 frustum.col(13) = nearTopRight;
183 frustum.col(14) = nearBottomRight;
184
185 frustum.col(15) = farTopRight;
186 frustum.col(16) = farTopLeft;
187 frustum.col(17) = farBottomLeft;
188
189
190 Eigen::Affine3f transform = Eigen::Affine3f::Identity();
191 transform *= Eigen::AngleAxisf(1.0 * M_PI, Eigen::Vector3f::UnitZ());
192
193
194 for (int i = 0; i < 18; i++)
195 {
196 Eigen::Vector4f temp = Eigen::Vector4f::Zero();
197
198 temp.head<3>() = frustum.col(i);
199
200 frustum.col(i) =
201 cameraToWorld.block<3, 3>(0, 0) * transform.matrix().block<3, 3>(0, 0) * frustum.col(i);
202 frustum.col(i) += cameraToWorld.col(3).head<3>();
203 }
204
205 return frustum;
206}
207
208bool
209PrimitiveFilter::intersectsFrustum(Eigen::Matrix4f pose, Eigen::Vector3f extent)
210{
211 Eigen::Vector3f a = pose.block<3, 3>(0, 0) * extent;
212
213 Eigen::Matrix3Xf points(3, 8);
214 points.col(0) = Eigen::Vector3f(a(0), a(1), a(2));
215 points.col(1) = Eigen::Vector3f(a(0), a(1), -a(2));
216 points.col(2) = Eigen::Vector3f(a(0), -a(1), a(2));
217 points.col(3) = Eigen::Vector3f(a(0), -a(1), -a(2));
218 points.col(4) = Eigen::Vector3f(-a(0), a(1), a(2));
219 points.col(5) = Eigen::Vector3f(-a(0), a(1), -a(2));
220 points.col(6) = Eigen::Vector3f(-a(0), -a(1), a(2));
221 points.col(7) = Eigen::Vector3f(-a(0), -a(1), -a(2));
222
223 for (int i = 0; i < 8; i++)
224 {
225 Eigen::Vector3f point = pose.col(3).head<3>() + points.col(i);
226 if (isPointInFrustum(point))
227 {
228 return true;
229 }
230 }
231
232 return false;
233}
234
235bool
237{
238 for (int i = 0; i < 18; i += 3)
239 {
240 Eigen::Vector3f u = frustum.col(i) - frustum.col(i + 1);
241 Eigen::Vector3f v = frustum.col(i) - frustum.col(i + 2);
242 Eigen::Vector3f normal = u.cross(v);
243 float dist = -1 * frustum.col(i).dot(normal);
244 if (normal.dot(point) + dist < 0)
245 {
246 return false;
247 }
248 }
249 return true;
250}
#define M_PI
Definition MathTools.h:17
Eigen::Matrix3Xf updateCameraPosition(Eigen::Matrix4f cameraToWorld)
adapted from https://github.com/vanderlin/FrustumCulling/
bool intersectsFrustum(Eigen::Matrix4f pose, Eigen::Vector3f extent)
void visualizeFrustum(DebugDrawerInterfacePrx debugDrawerTopicPrx)
PrimitiveFilter()
PrimitiveFilter Constructor.
void getPrimitivesInFieldOfView(std::vector< memoryx::EnvironmentalPrimitiveBasePtr > allPrimitives, std::vector< memoryx::EnvironmentalPrimitiveBasePtr > &visiblePrimitives, std::vector< memoryx::EnvironmentalPrimitiveBasePtr > &otherPrimitives)
bool isPointInFrustum(Eigen::Vector3f point)
~PrimitiveFilter()
PrimitiveFilter Destructor.
The Vector3 class.
Definition Pose.h:113
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
This file offers overloads of toIce() and fromIce() functions for STL container types.
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition algorithm.h:351
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx