PeriDyno 1.0.0
Loading...
Searching...
No Matches
DragVertexInteraction.cu
Go to the documentation of this file.
1#include "DragVertexInteraction.h"
2#include <thrust/sort.h>
3#include <iostream>
4#include <OrbitCamera.h>
5#define max_vel (10)
6namespace dyno
7{
8
9 template<typename TDataType>
10 DragVertexInteraction<TDataType>::DragVertexInteraction()
11 {
12 this->ray1 = TRay3D<Real>();
13 this->ray2 = TRay3D<Real>();
14 this->isPressed = false;
15 this->intersectionCenter.resize(1);
16 this->needInit = true;
17 }
18
19 template<typename TDataType>
20 void DragVertexInteraction<TDataType>::onEvent(PMouseEvent event)
21 {
22 if (this->needInit) {
23 this->restoreAttribute.assign(this->inAttribute()->getData());
24 needInit = false;
25 this->varCacheEvent()->setValue(true);
26 }
27
28 if (!event.altKeyPressed()) {
29 if (camera == nullptr)
30 {
31 this->camera = event.camera;
32 }
33
34 if (event.actionType == AT_PRESS)
35 {
36 this->camera = event.camera;
37 this->isPressed = true;
38 this->ray1.origin = event.ray.origin;
39 this->ray1.direction = event.ray.direction;
40 this->x1 = event.x;
41 this->y1 = event.y;
42
43 this->InteractionClick();
44 printf("Mouse pressed: Origin: %f %f %f; Direction: %f %f %f \n", event.ray.origin.x, event.ray.origin.y, event.ray.origin.z, event.ray.direction.x, event.ray.direction.y, event.ray.direction.z);
45 }
46 else if (event.actionType == AT_RELEASE && this->isPressed)
47 {
48 this->isPressed = false;
49 this->cancelVelocity();
50 this->inAttribute()->getData().assign(this->restoreAttribute);
51 this->intersectionCenter.reset();
52 printf("Mouse released: Origin: %f %f %f; Direction: %f %f %f \n", event.ray.origin.x, event.ray.origin.y, event.ray.origin.z, event.ray.direction.x, event.ray.direction.y, event.ray.direction.z);
53
54 }
55 else //pressed while moving(drag action) or just moving
56 {
57
58 if (this->isPressed)
59 {
60 this->ray2.origin = event.ray.origin;
61 this->ray2.direction = event.ray.direction;
62 this->x2 = event.x;
63 this->y2 = event.y;
64 if (this->x2 == this->x1 && this->y2 == this->y1)
65 {
66 //nothing need
67 }
68 else
69 {
70 this->InteractionDrag();
71 printf("Mouse repeated Draging: Origin: %f %f %f; Direction: %f %f %f \n", event.ray.origin.x, event.ray.origin.y, event.ray.origin.z, event.ray.direction.x, event.ray.direction.y, event.ray.direction.z);
72
73 }
74 //swap
75 this->ray1.origin = event.ray.origin;
76 this->ray1.direction = event.ray.direction;
77 this->x1 = event.x;
78 this->y1 = event.y;
79 }
80 }
81 }
82 }
83
84 __global__ void DV_PointInitializeArray(
85 DArray<int> intersected)
86 {
87 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
88 if (pId >= intersected.size()) return;
89
90 intersected[pId] = 0;
91 }
92
93 __global__ void DV_SurfaceInitializeArray(
94 DArray<int> intersected)
95 {
96 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
97 if (pId >= intersected.size()) return;
98
99 intersected[pId] = 0;
100 }
101
102 template <typename Triangle, typename Real, typename Coord>
103 __global__ void DV_CalcIntersectedTrisRay(
104 DArray<Coord> points,
105 DArray<Triangle> triangles,
106 DArray<int> intersected,
107 DArray<Coord> interPoints,
108 TRay3D<Real> mouseray)
109 {
110 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
111 if (pId >= triangles.size()) return;
112
113 TTriangle3D<Real> t = TTriangle3D<Real>(points[triangles[pId][0]], points[triangles[pId][1]], points[triangles[pId][2]]);
114 int temp = 0;
115
116 TPoint3D<Real> p;
117 temp = mouseray.intersect(t, p);
118
119 if (temp == 1 || intersected[pId] == 1)
120 {
121 intersected[pId] = 1;
122 interPoints[pId] = p.origin;
123 }
124 else
125 {
126 intersected[pId] = 0;
127 interPoints[pId] = Vec3f(0);
128 }
129 }
130
131 template <typename Real, typename Coord>
132 __global__ void DV_CalcTrisDistance(
133 DArray<Coord> interPoints,
134 DArray<Real> trisDistance,
135 DArray<int> intersected,
136 TRay3D<Real> mouseray)
137 {
138 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
139 if (pId >= interPoints.size()) return;
140 if (intersected[pId] !=0)
141 {
142 TPoint3D<Real> origin = TPoint3D<Real>(mouseray.origin);
143 TPoint3D<Real> p = TPoint3D<Real>(interPoints[pId]);
144 trisDistance[pId] = origin.distance(TPoint3D<Real>(p));
145 }
146 else
147 {
148 trisDistance[pId] = 3.4E38;
149 }
150 }
151
152 template <typename Real, typename Coord>
153 __global__ void DV_CalcIntersectedPointsRay(
154 DArray<Coord> points,
155 DArray<int> intersected,
156 TRay3D<Real> mouseray,
157 Real radius)
158 {
159 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
160 if (pId >= points.size()) return;
161
162 TSphere3D<Real> sphere = TSphere3D<Real>(points[pId], radius);
163 TSegment3D<Real> seg;
164 int temp = mouseray.intersect(sphere, seg);
165 if (temp > 0 || intersected[pId] == 1)
166 intersected[pId] = 1;
167 else
168 intersected[pId] = 0;
169 }
170
171 template <typename Coord, typename Real>
172 __global__ void DV_FindNearbyPoints(
173 DArray<Coord> points,
174 DArray<Coord> interPoints,
175 DArray<int> intersected,
176 int min_index_t,
177 Real intersectionRadius,
178 DArray<Coord> center)
179 {
180 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
181 if (pId >= intersected.size()) return;
182
183 if (intersected[pId] == 1)
184 {
185 TPoint3D<Real> p1 = TPoint3D<Real>(points[pId]);
186 TPoint3D<Real> p2 = TPoint3D<Real>(interPoints[min_index_t]);
187 center[0] = p2.origin;
188 if (p1.distance(p2) > intersectionRadius)
189 {
190 intersected[pId] = 0;
191 }
192 }
193 }
194
195 __global__ void DV_AssignOutPoints(
196 DArray<int> intersected_points,
197 DArray<int> intersected,
198 DArray<int> intersected_o)
199 {
200 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
201 if (pId >= intersected_o.size()) return;
202
203 if (intersected_o[pId] == 1)
204 {
205 intersected_points[intersected[pId]] = pId;
206 }
207 }
208
209
210 template<typename TDataType>
211 void DragVertexInteraction<TDataType>::calcVertexInteractClick()
212 {
213
214 auto& initialTriangleSet = this->inInitialTriangleSet()->getData();
215 auto& points = initialTriangleSet.getPoints();
216 auto& triangles = initialTriangleSet.getTriangles();
217 DArray<int> intersected_t;
218 intersected_t.resize(triangles.size());
219
220 cuExecute(triangles.size(),
221 DV_SurfaceInitializeArray,
222 intersected_t
223 );
224
225 DArray<Coord> interPoints_t;
226 interPoints_t.resize(triangles.size());
227
228 cuExecute(triangles.size(),
229 DV_CalcIntersectedTrisRay,
230 points,
231 triangles,
232 intersected_t,
233 interPoints_t,
234 this->ray1
235 );
236
237
238 DArray<Real> trisDistance;
239 trisDistance.resize(interPoints_t.size());
240
241 cuExecute(interPoints_t.size(),
242 DV_CalcTrisDistance,
243 interPoints_t,
244 trisDistance,
245 intersected_t,
246 this->ray1
247 );
248
249 int min_index_t = thrust::min_element(thrust::device, trisDistance.begin(), trisDistance.begin() + trisDistance.size()) - trisDistance.begin();
250
251 DArray<int> intersected_v;
252 intersected_v.resize(points.size());
253
254 cuExecute(points.size(),
255 DV_PointInitializeArray,
256 intersected_v
257 );
258
259
260 cuExecute(points.size(),
261 DV_CalcIntersectedPointsRay,
262 points,
263 intersected_v,
264 this->ray1,
265 this->varInterationRadius()->getData()
266 );
267
268 this->intersectionCenter.resize(1);
269
270 cuExecute(points.size(),
271 DV_FindNearbyPoints,
272 points,
273 interPoints_t,
274 intersected_v,
275 min_index_t,
276 this->varInterationRadius()->getData(),
277 this->intersectionCenter
278 );
279
280 this->verIntersectedIndex.assign(intersected_v);
281
282 DArray<int> intersected_o;
283 intersected_o.assign(intersected_v);
284
285 int intersected_size = thrust::reduce(thrust::device, intersected_v.begin(), intersected_v.begin() + intersected_v.size(), (int)0, thrust::plus<int>());
286 thrust::exclusive_scan(thrust::device, intersected_v.begin(), intersected_v.begin() + intersected_v.size(), intersected_v.begin());
287 this->intersected_vertex.resize(intersected_size);
288
289 cuExecute(points.size(),
290 DV_AssignOutPoints,
291 intersected_vertex,
292 intersected_v,
293 intersected_o
294 );
295
296 intersected_o.clear();
297 intersected_t.clear();
298 intersected_v.clear();
299
300 }
301
302 template <typename Real, typename Coord>
303 __global__ void DV_SetFollowed(
304 DArray<Attribute> att,
305 DArray<Attribute> restore_att,
306 DArray<Coord> Velocity,
307 DArray<Coord> Position,
308 Real timestep) {
309 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
310 if (pId >= att.size()) return;
311
312 if (!restore_att[pId].isFixed() && att[pId].isFixed()) { //set fixed by drag
313 Position[pId] += Velocity[pId] * timestep;
314 }
315
316 }
317
318 template<typename TDataType>
319 void DragVertexInteraction<TDataType>::cancelVelocity() {
320
321 CArray<Coord> movement_c;
322 movement_c.resize(1);
323 movement_c[0] = Coord(0);
324 DArray<Coord> movement;
325 movement.resize(1);
326 movement.assign(movement_c);
327
328 cuExecute(this->intersected_vertex.size(),
329 DV_SetupVelocity,
330 this->inVelocity()->getData(),
331 movement,
332 this->intersected_vertex,
333 this->inTimeStep()->getData()
334 );
335 movement_c.clear();
336 movement.clear();
337 }
338
339 template <typename Real, typename Coord>
340 __global__ void DV_SetupVelocity(
341 DArray<Coord> Velocity,
342 DArray<Coord> movement,
343 DArray<int> intersectionList,
344 Real timestep)
345 {
346 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
347 if (pId >= intersectionList.size()) return;
348
349 Coord velocity_candidate = movement[0] / timestep;
350 if (velocity_candidate.norm() >= max_vel)
351 velocity_candidate /= (velocity_candidate.norm() / max_vel);
352
353 Velocity[intersectionList[pId]] = velocity_candidate;
354 }
355
356 template<typename TDataType>
357 void DragVertexInteraction<TDataType>::calcVertexInteractDrag()
358
359 {
360
361 TRay3D<Real> ray1 = this->ray1;
362 TRay3D<Real> ray2 = this->ray2;
363
364 TRay3D<Real> ray_o = this->camera->castRayInWorldSpace((float)0.0, (float)0.0);
365
366 float height = this->camera->viewportHeight()/2.0;
367 float width = this->camera->viewportWidth()/2.0;
368 TRay3D<Real> ray_horizon = this->camera->castRayInWorldSpace(width, (float)0.0);
369 TRay3D<Real> ray_vertical = this->camera->castRayInWorldSpace((float)0.0, height);
370
371 //printf("(x1,y1) = %f,%f (x2,y2) = %f,%f\n", x1, y1, x2, y2);
372 auto ray_h = ray_o.origin - ray_horizon.origin;
373 auto ray_v = ray_o.origin - ray_vertical.origin;
374 auto N_plane = ray_h.cross(ray_v);
375
376 if (N_plane.norm() == 0.0) //error
377 return;
378
379 N_plane /= N_plane.norm();
380 CArray<Coord> movement_c; //this will be used to calc velocity
381 CArray<Coord> center; //this is previous intersectionCenter
382 center.resize(1);
383 center.assign(this->intersectionCenter);
384 movement_c.resize(1);
385 movement_c.assign(this->intersectionCenter);
386
387 TPlane3D<Real> focal_plane = TPlane3D<Real>(center[0], N_plane);
388 TPoint3D<Real> p;
389 int temp = ray2.intersect(focal_plane, p);
390 movement_c[0] = p.origin-center[0];
391
392 DArray<Coord> movement;
393 movement.resize(1);
394 movement.assign(movement_c);
395
396 Real dt = (Real)this->inTimeStep()->getData();
397 Coord velocity_candidate = movement_c[0] / dt;
398 if (velocity_candidate.norm() >= max_vel)
399 velocity_candidate /= (velocity_candidate.norm() / max_vel);
400
401 center[0] += velocity_candidate * dt;
402 this->intersectionCenter.assign(center);
403
404 cuExecute(this->intersected_vertex.size(),
405 DV_SetupVelocity,
406 this->inVelocity()->getData(),
407 movement,
408 this->intersected_vertex,
409 this->inTimeStep()->getData()
410 );
411 cuSynchronize();
412
413 cuExecute(this->inPosition()->getData().size(),
414 DV_SetFollowed,
415 this->inAttribute()->getData(),
416 this->restoreAttribute,
417 this->inVelocity()->getData(),
418 this->inPosition()->getData(),
419 this->inTimeStep()->getData()
420 );
421 movement.clear();
422 movement_c.clear();
423 center.clear();
424 //printf("==============================end intersection================================\n");
425 }
426
427
428 __global__ void DV_FixedPoint(
429 DArray<int> intersected_vertex,
430 DArray<Attribute> inAtt) {
431
432 int vId = threadIdx.x + (blockIdx.x * blockDim.x);
433 if (vId >= intersected_vertex.size()) return;
434
435 Attribute& att = inAtt[intersected_vertex[vId]];
436 att.setFixed();
437 }
438
439 template<typename TDataType>
440 void DragVertexInteraction<TDataType>::setVertexFixed() {
441 cuExecute(this->intersected_vertex.size(),
442 DV_FixedPoint,
443 this->intersected_vertex,
444 this->inAttribute()->getData()
445 );
446 }
447
448
449 template<typename TDataType>
450 void DragVertexInteraction<TDataType>::InteractionClick()
451 {
452
453 calcVertexInteractClick();
454 this->setVertexFixed();
455
456
457 }
458
459 template<typename TDataType>
460 void DragVertexInteraction<TDataType>::InteractionDrag()
461 {
462
463 calcVertexInteractDrag();
464
465 }
466
467 DEFINE_CLASS(DragVertexInteraction);
468}