1#include "DragVertexInteraction.h"
2#include <thrust/sort.h>
4#include <OrbitCamera.h>
9 template<typename TDataType>
10 DragVertexInteraction<TDataType>::DragVertexInteraction()
12 this->ray1 = TRay3D<Real>();
13 this->ray2 = TRay3D<Real>();
14 this->isPressed = false;
15 this->intersectionCenter.resize(1);
16 this->needInit = true;
19 template<typename TDataType>
20 void DragVertexInteraction<TDataType>::onEvent(PMouseEvent event)
23 this->restoreAttribute.assign(this->inAttribute()->getData());
25 this->varCacheEvent()->setValue(true);
28 if (!event.altKeyPressed()) {
29 if (camera == nullptr)
31 this->camera = event.camera;
34 if (event.actionType == AT_PRESS)
36 this->camera = event.camera;
37 this->isPressed = true;
38 this->ray1.origin = event.ray.origin;
39 this->ray1.direction = event.ray.direction;
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);
46 else if (event.actionType == AT_RELEASE && this->isPressed)
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);
55 else //pressed while moving(drag action) or just moving
60 this->ray2.origin = event.ray.origin;
61 this->ray2.direction = event.ray.direction;
64 if (this->x2 == this->x1 && this->y2 == this->y1)
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);
75 this->ray1.origin = event.ray.origin;
76 this->ray1.direction = event.ray.direction;
84 __global__ void DV_PointInitializeArray(
85 DArray<int> intersected)
87 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
88 if (pId >= intersected.size()) return;
93 __global__ void DV_SurfaceInitializeArray(
94 DArray<int> intersected)
96 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
97 if (pId >= intersected.size()) return;
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)
110 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
111 if (pId >= triangles.size()) return;
113 TTriangle3D<Real> t = TTriangle3D<Real>(points[triangles[pId][0]], points[triangles[pId][1]], points[triangles[pId][2]]);
117 temp = mouseray.intersect(t, p);
119 if (temp == 1 || intersected[pId] == 1)
121 intersected[pId] = 1;
122 interPoints[pId] = p.origin;
126 intersected[pId] = 0;
127 interPoints[pId] = Vec3f(0);
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)
138 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
139 if (pId >= interPoints.size()) return;
140 if (intersected[pId] !=0)
142 TPoint3D<Real> origin = TPoint3D<Real>(mouseray.origin);
143 TPoint3D<Real> p = TPoint3D<Real>(interPoints[pId]);
144 trisDistance[pId] = origin.distance(TPoint3D<Real>(p));
148 trisDistance[pId] = 3.4E38;
152 template <typename Real, typename Coord>
153 __global__ void DV_CalcIntersectedPointsRay(
154 DArray<Coord> points,
155 DArray<int> intersected,
156 TRay3D<Real> mouseray,
159 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
160 if (pId >= points.size()) return;
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;
168 intersected[pId] = 0;
171 template <typename Coord, typename Real>
172 __global__ void DV_FindNearbyPoints(
173 DArray<Coord> points,
174 DArray<Coord> interPoints,
175 DArray<int> intersected,
177 Real intersectionRadius,
178 DArray<Coord> center)
180 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
181 if (pId >= intersected.size()) return;
183 if (intersected[pId] == 1)
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)
190 intersected[pId] = 0;
195 __global__ void DV_AssignOutPoints(
196 DArray<int> intersected_points,
197 DArray<int> intersected,
198 DArray<int> intersected_o)
200 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
201 if (pId >= intersected_o.size()) return;
203 if (intersected_o[pId] == 1)
205 intersected_points[intersected[pId]] = pId;
210 template<typename TDataType>
211 void DragVertexInteraction<TDataType>::calcVertexInteractClick()
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());
220 cuExecute(triangles.size(),
221 DV_SurfaceInitializeArray,
225 DArray<Coord> interPoints_t;
226 interPoints_t.resize(triangles.size());
228 cuExecute(triangles.size(),
229 DV_CalcIntersectedTrisRay,
238 DArray<Real> trisDistance;
239 trisDistance.resize(interPoints_t.size());
241 cuExecute(interPoints_t.size(),
249 int min_index_t = thrust::min_element(thrust::device, trisDistance.begin(), trisDistance.begin() + trisDistance.size()) - trisDistance.begin();
251 DArray<int> intersected_v;
252 intersected_v.resize(points.size());
254 cuExecute(points.size(),
255 DV_PointInitializeArray,
260 cuExecute(points.size(),
261 DV_CalcIntersectedPointsRay,
265 this->varInterationRadius()->getData()
268 this->intersectionCenter.resize(1);
270 cuExecute(points.size(),
276 this->varInterationRadius()->getData(),
277 this->intersectionCenter
280 this->verIntersectedIndex.assign(intersected_v);
282 DArray<int> intersected_o;
283 intersected_o.assign(intersected_v);
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);
289 cuExecute(points.size(),
296 intersected_o.clear();
297 intersected_t.clear();
298 intersected_v.clear();
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,
309 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
310 if (pId >= att.size()) return;
312 if (!restore_att[pId].isFixed() && att[pId].isFixed()) { //set fixed by drag
313 Position[pId] += Velocity[pId] * timestep;
318 template<typename TDataType>
319 void DragVertexInteraction<TDataType>::cancelVelocity() {
321 CArray<Coord> movement_c;
322 movement_c.resize(1);
323 movement_c[0] = Coord(0);
324 DArray<Coord> movement;
326 movement.assign(movement_c);
328 cuExecute(this->intersected_vertex.size(),
330 this->inVelocity()->getData(),
332 this->intersected_vertex,
333 this->inTimeStep()->getData()
339 template <typename Real, typename Coord>
340 __global__ void DV_SetupVelocity(
341 DArray<Coord> Velocity,
342 DArray<Coord> movement,
343 DArray<int> intersectionList,
346 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
347 if (pId >= intersectionList.size()) return;
349 Coord velocity_candidate = movement[0] / timestep;
350 if (velocity_candidate.norm() >= max_vel)
351 velocity_candidate /= (velocity_candidate.norm() / max_vel);
353 Velocity[intersectionList[pId]] = velocity_candidate;
356 template<typename TDataType>
357 void DragVertexInteraction<TDataType>::calcVertexInteractDrag()
361 TRay3D<Real> ray1 = this->ray1;
362 TRay3D<Real> ray2 = this->ray2;
364 TRay3D<Real> ray_o = this->camera->castRayInWorldSpace((float)0.0, (float)0.0);
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);
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);
376 if (N_plane.norm() == 0.0) //error
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
383 center.assign(this->intersectionCenter);
384 movement_c.resize(1);
385 movement_c.assign(this->intersectionCenter);
387 TPlane3D<Real> focal_plane = TPlane3D<Real>(center[0], N_plane);
389 int temp = ray2.intersect(focal_plane, p);
390 movement_c[0] = p.origin-center[0];
392 DArray<Coord> movement;
394 movement.assign(movement_c);
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);
401 center[0] += velocity_candidate * dt;
402 this->intersectionCenter.assign(center);
404 cuExecute(this->intersected_vertex.size(),
406 this->inVelocity()->getData(),
408 this->intersected_vertex,
409 this->inTimeStep()->getData()
413 cuExecute(this->inPosition()->getData().size(),
415 this->inAttribute()->getData(),
416 this->restoreAttribute,
417 this->inVelocity()->getData(),
418 this->inPosition()->getData(),
419 this->inTimeStep()->getData()
424 //printf("==============================end intersection================================\n");
428 __global__ void DV_FixedPoint(
429 DArray<int> intersected_vertex,
430 DArray<Attribute> inAtt) {
432 int vId = threadIdx.x + (blockIdx.x * blockDim.x);
433 if (vId >= intersected_vertex.size()) return;
435 Attribute& att = inAtt[intersected_vertex[vId]];
439 template<typename TDataType>
440 void DragVertexInteraction<TDataType>::setVertexFixed() {
441 cuExecute(this->intersected_vertex.size(),
443 this->intersected_vertex,
444 this->inAttribute()->getData()
449 template<typename TDataType>
450 void DragVertexInteraction<TDataType>::InteractionClick()
453 calcVertexInteractClick();
454 this->setVertexFixed();
459 template<typename TDataType>
460 void DragVertexInteraction<TDataType>::InteractionDrag()
463 calcVertexInteractDrag();
467 DEFINE_CLASS(DragVertexInteraction);