TDME2  1.9.200
Gizmo.cpp
Go to the documentation of this file.
2 
3 #include <array>
4 
5 #include <tdme/tdme.h>
9 #include <tdme/engine/Camera.h>
10 #include <tdme/engine/Engine.h>
11 #include <tdme/engine/Entity.h>
12 #include <tdme/engine/Frustum.h>
13 #include <tdme/engine/Object.h>
14 #include <tdme/engine/Transform.h>
15 #include <tdme/math/Math.h>
16 #include <tdme/math/Matrix4x4.h>
17 #include <tdme/math/Quaternion.h>
18 #include <tdme/math/Vector3.h>
19 #include <tdme/math/Vector4.h>
21 #include <tdme/utilities/Console.h>
23 
25 
26 using std::array;
27 
37 using tdme::math::Math;
45 
46 Gizmo::Gizmo(Engine* engine, const string& id, int32_t gizmoTypeMask)
47 {
48  this->engine = engine;
49  this->id = id;
50  this->gizmoTypeMask = gizmoTypeMask;
60 }
61 
63 }
64 
65 void Gizmo::updateGizmo(const Vector3& gizmoTranslation, const Transform& transform) {
66  this->gizmoTranslation = gizmoTranslation;
68  Object* gizmoEntity = nullptr;
69  switch (getGizmoType()) {
70  case GIZMOTYPE_ALL:
71  {
75  engine->removeEntity(id + ".tdme.gizmo.translation");
76  engine->removeEntity(id + ".tdme.gizmo.scale");
77  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.all"));
78  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.all", Tools::getGizmoAll()));
79  gizmoEntity->setPickable(true);
80  gizmoEntity->setFrustumCulling(false);
81  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
84  gizmoEntity->update();
85  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.rotations"));
86  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.rotations", Tools::getGizmoRotations()));
87  gizmoEntity->setPickable(true);
88  gizmoEntity->setFrustumCulling(false);
89  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
92  gizmoEntity->update();
93  } else
96  engine->removeEntity(id + ".tdme.gizmo.translation");
97  engine->removeEntity(id + ".tdme.gizmo.rotations");
98  engine->removeEntity(id + ".tdme.gizmo.scale");
99  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.all"));
100  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.all", Tools::getGizmoTranslationScale()));
101  gizmoEntity->setPickable(true);
102  gizmoEntity->setFrustumCulling(false);
103  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
106  gizmoEntity->update();
107  } else {
109  engine->removeEntity(id + ".tdme.gizmo.all");
110  engine->removeEntity(id + ".tdme.gizmo.rotations");
111  engine->removeEntity(id + ".tdme.gizmo.scale");
112  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.translation"));
113  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.translation", Tools::getGizmoTranslation()));
114  gizmoEntity->setPickable(true);
115  gizmoEntity->setFrustumCulling(false);
116  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
119  gizmoEntity->update();
120  }
122  engine->removeEntity(id + ".tdme.gizmo.all");
123  engine->removeEntity(id + ".tdme.gizmo.translation");
124  engine->removeEntity(id + ".tdme.gizmo.scale");
125  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.rotations"));
126  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.rotations", Tools::getGizmoRotations()));
127  gizmoEntity->setPickable(true);
128  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
131  gizmoEntity->update();
132  }
134  engine->removeEntity(id + ".tdme.gizmo.all");
135  engine->removeEntity(id + ".tdme.gizmo.translation");
136  engine->removeEntity(id + ".tdme.gizmo.rotations");
137  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.scale"));
138  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.scale", Tools::getGizmoScale()));
139  gizmoEntity->setPickable(true);
140  gizmoEntity->setFrustumCulling(false);
141  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
144  gizmoEntity->update();
145  }
146  }
147  break;
148  }
149  case GIZMOTYPE_TRANSLATE:
150  {
151  engine->removeEntity(id + ".tdme.gizmo.all");
152  engine->removeEntity(id + ".tdme.gizmo.scale");
153  engine->removeEntity(id + ".tdme.gizmo.rotations");
154  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.translation"));
155  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.translation", Tools::getGizmoTranslation()));
156  gizmoEntity->setPickable(true);
157  gizmoEntity->setFrustumCulling(false);
158  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
161  gizmoEntity->update();
162  break;
163  }
164  case GIZMOTYPE_ROTATE:
165  {
166  engine->removeEntity(id + ".tdme.gizmo.all");
167  engine->removeEntity(id + ".tdme.gizmo.translation");
168  engine->removeEntity(id + ".tdme.gizmo.scale");
169  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.rotations"));
170  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.rotations", Tools::getGizmoRotations()));
171  gizmoEntity->setPickable(true);
172  gizmoEntity->setFrustumCulling(false);
173  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
176  gizmoEntity->update();
177  break;
178  }
179  case GIZMOTYPE_SCALE:
180  {
181  engine->removeEntity(id + ".tdme.gizmo.all");
182  engine->removeEntity(id + ".tdme.gizmo.translation");
183  engine->removeEntity(id + ".tdme.gizmo.rotations");
184  gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.scale"));
185  if (gizmoEntity == nullptr) engine->addEntity(gizmoEntity = new Object(id + ".tdme.gizmo.scale", Tools::getGizmoScale()));
186  gizmoEntity->setPickable(true);
187  gizmoEntity->setFrustumCulling(false);
188  gizmoEntity->setRenderPass(Entity::RENDERPASS_GIZMO);
191  gizmoEntity->update();
192  break;
193  }
194  case GIZMOTYPE_NONE:
195  break;
196  }
197  setGizmoRotation(transform);
198 }
199 
201  auto gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.all"));
202  if (gizmoEntity == nullptr) gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.translation"));
203  if (gizmoEntity == nullptr) gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.rotations"));
204  if (gizmoEntity == nullptr) gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.scale"));
205  return gizmoEntity;
206 }
207 
209  engine->removeEntity(id + ".tdme.gizmo.all");
210  engine->removeEntity(id + ".tdme.gizmo.translation");
211  engine->removeEntity(id + ".tdme.gizmo.scale");
212  engine->removeEntity(id + ".tdme.gizmo.rotations");
214 }
215 
216 bool Gizmo::determineGizmoMovement(int mouseX, int mouseY, int axisIdx, const Vector3& axis, Vector3& deltaMovement) {
217  // engine mouse position for near, far
218  auto nearPlaneWorldCoordinate = engine->computeWorldCoordinateByMousePosition(mouseX, mouseY, 0.0f);
219  auto farPlaneWorldCoordinate = engine->computeWorldCoordinateByMousePosition(mouseX, mouseY, 1.0f);
220 
221  //
222  Vector3 axisMin = axis.clone().scale(-5000.0f);
223  Vector3 axisMax = axis.clone().scale(5000.0f);
224 
225  //
226  axisMin.add(gizmoTranslation);
227  axisMax.add(gizmoTranslation);
228 
229  // compute closest points on near, far mouse positions line segment and axis
230  Vector3 gizmoTranslationOnAxis;
231  Vector3 gizmoTranslationOnAxisTmp;
232  LineSegment::computeClosestPointsOnLineSegments(axisMin, axisMax, nearPlaneWorldCoordinate, farPlaneWorldCoordinate, gizmoTranslationOnAxis, gizmoTranslationOnAxisTmp);
233 
234  //
235  if (gizmoTranslationHandleDiffAvailable[axisIdx] == false) {
236  gizmoTranslationHandleDiff[axisIdx] = gizmoTranslationOnAxis.clone().sub(gizmoTranslation);
237  gizmoTranslationHandleDiffAvailable[axisIdx] = true;
238  }
239 
240  // do we already have a old result
241  auto success = gizmoTranslationLastResultAvailable[axisIdx] == true;
242  if (success == true) {
243  deltaMovement[axisIdx] = gizmoTranslationOnAxis.clone().sub(gizmoTranslationLastResult[axisIdx])[axisIdx];
244  auto movementLength = gizmoTranslation.clone().sub(gizmoTranslationOnAxis.clone().sub(gizmoTranslationHandleDiff[axisIdx])).computeLength();
245  if (deltaMovement[axisIdx] < Math::EPSILON) {
246  deltaMovement[axisIdx] = -1.0f;
247  deltaMovement[axisIdx]*= movementLength;
248  } else
249  if (deltaMovement[axisIdx] > Math::EPSILON) {
250  deltaMovement[axisIdx] = 1.0f;
251  deltaMovement[axisIdx]*= movementLength;
252  } else {
253  deltaMovement[axisIdx] = 0.0f;
254  }
255  }
256 
257  // what ever, we have a new one
258  gizmoTranslationLastResult[axisIdx] = gizmoTranslationOnAxis;
259  gizmoTranslationLastResultAvailable[axisIdx] = true;
260 
261  //
262  return success;
263 }
264 
265 bool Gizmo::determineGizmoScale(int mouseX, int mouseY, int axisIdx, const Vector3& axis, Vector3& deltaScale) {
266  auto nearPlaneWorldCoordinate = engine->computeWorldCoordinateByMousePosition(mouseX, mouseY, 0.0f);
267  auto farPlaneWorldCoordinate = engine->computeWorldCoordinateByMousePosition(mouseX, mouseY, 1.0f);
268 
269  //
270  Vector3 axisMin = axis.clone().scale(-5000.0f);
271  Vector3 axisMax = axis.clone().scale(5000.0f);
272 
273  //
274  axisMin.add(gizmoTranslation);
275  axisMax.add(gizmoTranslation);
276 
277  //
278  Vector3 contactOnAxis;
279  Vector3 contactOnAxisTmp;
280  LineSegment::computeClosestPointsOnLineSegments(axisMin, axisMax, nearPlaneWorldCoordinate, farPlaneWorldCoordinate, contactOnAxis, contactOnAxisTmp);
281  auto success = gizmoTranslationLastResultAvailable[axisIdx] == true;
282  if (success == true) {
283  auto direction = 1.0f;
284  if (gizmoTranslationLastResult[axisIdx].clone().sub(gizmoTranslation).computeLengthSquared() > contactOnAxis.clone().sub(gizmoTranslation).computeLengthSquared()) direction = -1.0f;
285  deltaScale[axisIdx] = contactOnAxis.clone().sub(gizmoTranslationLastResult[axisIdx]).computeLength() * direction;
286  }
287  gizmoTranslationLastResult[axisIdx] = contactOnAxis;
288  gizmoTranslationLastResultAvailable[axisIdx] = true;
289  return success;
290 }
291 
292 bool Gizmo::determineGizmoRotation(int mouseX, int mouseY, const array<Vector3, 4>& vertices, const Vector3& planeNormal, float& deltaRotation) {
293  auto nearPlaneWorldCoordinate = engine->computeWorldCoordinateByMousePosition(mouseX, mouseY, 0.0f);
294  auto farPlaneWorldCoordinate = engine->computeWorldCoordinateByMousePosition(mouseX, mouseY, 1.0f);
295  Vector3 lineTriangleContact;
296  auto transformedVertices = vertices;
297  for (auto& vertex: transformedVertices) {
298  vertex.add(gizmoTranslation);
299  }
300  if (LineSegment::doesLineSegmentCollideWithTriangle(
301  transformedVertices[0],
302  transformedVertices[1],
303  transformedVertices[2],
304  nearPlaneWorldCoordinate,
305  farPlaneWorldCoordinate,
306  lineTriangleContact) == true ||
307  LineSegment::doesLineSegmentCollideWithTriangle(
308  transformedVertices[2],
309  transformedVertices[3],
310  transformedVertices[0],
311  nearPlaneWorldCoordinate,
312  farPlaneWorldCoordinate,
313  lineTriangleContact) == true
314  ) {
315  auto success = gizmoRotationLastResultAvailable == true;
316  if (success == true) {
317  auto a = lineTriangleContact.clone().sub(gizmoTranslation).normalize();
319  deltaRotation = Vector3::computeAngle(a, b, planeNormal);
320  if (deltaRotation > 180.0f) deltaRotation = deltaRotation - 360.0f;
321  }
322  gizmoRotationLastResult = lineTriangleContact;
324  return success;
325  }
326  return false;
327 }
328 
329 bool Gizmo::determineGizmoDeltaTransformations(int mouseX, int mouseY, Vector3& deltaTranslation, Vector3& deltaRotation, Vector3& deltaScale) {
330  if (getGizmoMode() == GIZMOMODE_NONE) return false;
331 
332  //
333  deltaTranslation.set(0.0f, 0.0f, 0.0f);
334  deltaRotation.set(0.0f, 0.0f, 0.0f);
335  deltaScale.set(1.0f, 1.0f, 1.0f);
336  Vector3 gizmoMovement;
337 
338  //
339  const Vector3 planeXYNormal(0.0f, 0.0f, -1.0f);
340  const array<Vector3, 4> planeXY = {
341  Vector3(-5000.0f, -5000.0f, 0.0f),
342  Vector3(-5000.0f, 5000.0f, 0.0f),
343  Vector3(5000.0f, 5000.0f, 0.0f),
344  Vector3(5000.0f, -5000.0f, 0.0f)
345  };
346 
347  //
348  const Vector3 planeXZNormal(0.0f, -1.0f, 0.0f);
349  const array<Vector3, 4> planeXZ = {
350  Vector3(-5000.0f, 0.0f, -5000.0f),
351  Vector3(-5000.0f, 0.0f, 5000.0f),
352  Vector3(5000.0f, 0.0f, 5000.0f),
353  Vector3(5000.0f, 0.0f, -5000.0f)
354  };
355 
356  //
357  const Vector3 planeYZNormal(-1.0f, 0.0f, 0.0f);
358  const array<Vector3, 4> planeYZ = {
359  Vector3(0.0f, -5000.0f, -5000.0f),
360  Vector3(0.0f, -5000.0f, 5000.0f),
361  Vector3(0.0f, 5000.0f, 5000.0f),
362  Vector3(0.0f, 5000.0f, -5000.0f)
363  };
364 
365  //
366  switch (getGizmoMode()) {
368  {
369  if (determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_X, Vector3(1.0f, 0.0, 0.0f), gizmoMovement) == true) {
370  deltaTranslation.setX(gizmoMovement.getX());
371  }
372  break;
373  }
375  {
376  if (determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Y, Vector3(0.0f, 1.0, 0.0f), gizmoMovement) == true) {
377  deltaTranslation.setY(gizmoMovement.getY());
378  }
379  break;
380  }
382  {
383  if (determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Z, Vector3(0.0f, 0.0, 1.0f), gizmoMovement) == true) {
384  deltaTranslation.setZ(gizmoMovement.getZ());
385  }
386  break;
387  }
389  {
390  if (determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Y, Vector3(0.0f, 1.0, 0.0f), gizmoMovement) == true &&
391  determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Z, Vector3(0.0f, 0.0, 1.0f), gizmoMovement) == true) {
392  deltaTranslation.setY(gizmoMovement.getY());
393  deltaTranslation.setZ(gizmoMovement.getZ());
394  }
395  break;
396  }
398  {
399  if (determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_X, Vector3(1.0f, 0.0, 0.0f), gizmoMovement) == true &&
400  determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Z, Vector3(0.0f, 0.0, 1.0f), gizmoMovement) == true) {
401  deltaTranslation.setX(gizmoMovement.getX());
402  deltaTranslation.setZ(gizmoMovement.getZ());
403  }
404  break;
405  }
407  {
408  if (determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_X, Vector3(1.0f, 0.0, 0.0f), gizmoMovement) == true &&
409  determineGizmoMovement(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Y, Vector3(0.0f, 1.0, 0.0f), gizmoMovement) == true) {
410  deltaTranslation.setX(gizmoMovement.getX());
411  deltaTranslation.setY(gizmoMovement.getY());
412  }
413  break;
414  }
415  case GIZMOMODE_SCALE_X:
416  {
417  if (determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_X, rotationsMatrix.multiply(Vector3(1.0f, 0.0, 0.0f)).normalize(), gizmoMovement) == true) {
418  deltaScale.add(gizmoMovement);
419  }
420  break;
421  }
422  case GIZMOMODE_SCALE_Y:
423  {
424  if (determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Y, rotationsMatrix.multiply(Vector3(0.0f, 1.0, 0.0f)).normalize(), gizmoMovement) == true) {
425  deltaScale.add(gizmoMovement);
426  }
427  break;
428  }
429  case GIZMOMODE_SCALE_Z:
430  {
431  if (determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Z, rotationsMatrix.multiply(Vector3(0.0f, 0.0, 1.0f)).normalize(), gizmoMovement) == true) {
432  deltaScale.add(gizmoMovement);
433  }
434  break;
435  }
437  {
438  if (determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Y, Vector3(0.0f, 1.0, 0.0f), gizmoMovement) == true &&
439  determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Z, Vector3(0.0f, 0.0, 1.0f), gizmoMovement) == true) {
440  deltaScale.add(gizmoMovement);
441  }
442  break;
443  }
445  {
446  if (determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_X, Vector3(1.0f, 0.0, 0.0f), gizmoMovement) == true &&
447  determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Z, Vector3(0.0f, 0.0, 1.0f), gizmoMovement) == true) {
448  deltaScale.add(gizmoMovement);
449  }
450  break;
451  }
453  {
454  if (determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_X, Vector3(1.0f, 0.0, 0.0f), gizmoMovement) == true &&
455  determineGizmoScale(mouseX, mouseY, GizmoAxisIdx::GIZMOAXISIDX_Y, Vector3(0.0f, 1.0, 0.0f), gizmoMovement) == true) {
456  deltaScale.add(gizmoMovement);
457  }
458  break;
459  }
460  case GIZMOMODE_ROTATE_X:
461  {
462  const auto& planeVertices = planeYZ;
463  const auto& planeNormal = planeYZNormal;
464  float gizmoDeltaRotation = 0.0f;
465  auto vertices = planeVertices;
466  for (auto& vertex: vertices) {
467  vertex = rotationsMatrix.multiply(vertex);
468  }
469  auto planeNormalTransformed = rotationsMatrix.multiply(planeNormal).normalize();
470  if (determineGizmoRotation(mouseX, mouseY, vertices, planeNormalTransformed, gizmoDeltaRotation) == true) {
471  deltaRotation.setX(gizmoDeltaRotation);
472  break;
473  }
474  }
475  break;
476  case GIZMOMODE_ROTATE_Y:
477  {
478  const auto& planeVertices = planeXZ;
479  const auto& planeNormal = planeXZNormal;
480  float gizmoDeltaRotation = 0.0f;
481  auto vertices = planeVertices;
482  for (auto& vertex: vertices) {
483  vertex = rotationsMatrix.multiply(vertex);
484  }
485  auto planeNormalTransformed = rotationsMatrix.multiply(planeNormal).normalize();
486  if (determineGizmoRotation(mouseX, mouseY, vertices, planeNormalTransformed, gizmoDeltaRotation) == true) {
487  deltaRotation.setY(gizmoDeltaRotation);
488  break;
489  }
490  }
491  break;
492  case GIZMOMODE_ROTATE_Z:
493  {
494  const auto& planeVertices = planeXY;
495  const auto& planeNormal = planeXYNormal;
496  float gizmoDeltaRotation = 0.0f;
497  auto vertices = planeVertices;
498  for (auto& vertex: vertices) {
499  vertex = rotationsMatrix.multiply(vertex);
500  }
501  auto planeNormalTransformed = rotationsMatrix.multiply(planeNormal).normalize();
502  if (determineGizmoRotation(mouseX, mouseY, vertices, planeNormalTransformed, gizmoDeltaRotation) == true) {
503  deltaRotation.setZ(gizmoDeltaRotation);
504  break;
505  }
506  }
507  break;
508  case GIZMOMODE_NONE:
509  // no op, satisfy the compiler
510  break;
511  }
512  return true;
513 }
514 
515 bool Gizmo::determineGizmoMode(Entity* selectedEntity, Node* selectedEntityNode) {
516  if (selectedEntity != nullptr &&
517  StringTools::startsWith(selectedEntity->getId(), id + ".tdme.gizmo.") == true && selectedEntityNode != nullptr) {
518  auto selectedEntityNodeId = selectedEntityNode->getId();
519  if (StringTools::startsWith(selectedEntityNodeId, "all_") == true) selectedEntityNodeId = StringTools::substring(selectedEntityNodeId, 4);
520  if (selectedEntityNodeId == "translate_x") setGizmoMode(GIZMOMODE_TRANSLATE_X); else
521  if (selectedEntityNodeId == "translate_y") setGizmoMode(GIZMOMODE_TRANSLATE_Y); else
522  if (selectedEntityNodeId == "translate_z") setGizmoMode(GIZMOMODE_TRANSLATE_Z); else
523  if (selectedEntityNodeId == "translate_x_plane") setGizmoMode(GIZMOMODE_TRANSLATEPLANE_X); else
524  if (selectedEntityNodeId == "translate_y_plane") setGizmoMode(GIZMOMODE_TRANSLATEPLANE_Z); else
525  if (selectedEntityNodeId == "translate_z_plane") setGizmoMode(GIZMOMODE_TRANSLATEPLANE_Y); else
526  if (selectedEntityNodeId == "rotate_x") setGizmoMode(GIZMOMODE_ROTATE_X); else
527  if (selectedEntityNodeId == "rotate_y") setGizmoMode(GIZMOMODE_ROTATE_Y); else
528  if (selectedEntityNodeId == "rotate_z") setGizmoMode(GIZMOMODE_ROTATE_Z); else
529  if (selectedEntityNodeId == "scale_x") setGizmoMode(GIZMOMODE_SCALE_X); else
530  if (selectedEntityNodeId == "scale_y") setGizmoMode(GIZMOMODE_SCALE_Y); else
531  if (selectedEntityNodeId == "scale_z") setGizmoMode(GIZMOMODE_SCALE_Z); else
532  if (selectedEntityNodeId == "scale_x_plane") setGizmoMode(GIZMOMODE_SCALEPLANE_X); else
533  if (selectedEntityNodeId == "scale_y_plane") setGizmoMode(GIZMOMODE_SCALEPLANE_Y); else
534  if (selectedEntityNodeId == "scale_z_plane") setGizmoMode(GIZMOMODE_SCALEPLANE_Z); else
536  //
537  return true;
538  }
539  return false;
540 }
541 
542 void Gizmo::setGizmoRotation(const Transform& transform) {
543  auto cameraMatrixEuler = engine->getCamera()->getCameraMatrix().computeEulerAngles();
544  Transform cameraRotationTransformations;
545  cameraRotationTransformations.addRotation(Vector3(0.0f, 0.0f, 1.0f), cameraMatrixEuler.getZ());
546  cameraRotationTransformations.addRotation(Vector3(0.0f, 1.0f, 0.0f), cameraMatrixEuler.getY());
547  cameraRotationTransformations.addRotation(Vector3(1.0f, 0.0f, 0.0f), cameraMatrixEuler.getX());
548  cameraRotationTransformations.update();
549  //
551  {
552  auto gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.translation"));
553  if (gizmoEntity != nullptr) {
554  cameraRotationTransformations.setTranslation(gizmoEntity->getTranslation());
555  cameraRotationTransformations.setScale(gizmoEntity->getScale());
556  cameraRotationTransformations.update();
557  gizmoEntity->setTransform(cameraRotationTransformations);
558  gizmoEntity->update();
559  }
560  }
561  {
562  auto gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.rotations"));
563  if (gizmoEntity != nullptr) {
564  cameraRotationTransformations.setTranslation(gizmoEntity->getTranslation());
565  cameraRotationTransformations.setScale(gizmoEntity->getScale());
566  cameraRotationTransformations.update();
567  gizmoEntity->setTransform(cameraRotationTransformations);
568  gizmoEntity->setNodeTransformMatrix("rotate_x", rotationsMatrix);
569  gizmoEntity->setNodeTransformMatrix("rotate_y", rotationsMatrix);
570  gizmoEntity->setNodeTransformMatrix("rotate_z", rotationsMatrix);
571  gizmoEntity->update();
572  }
573  }
574  {
575  auto gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.scale"));
576  if (gizmoEntity != nullptr) {
577  cameraRotationTransformations.setTranslation(gizmoEntity->getTranslation());
578  cameraRotationTransformations.setScale(gizmoEntity->getScale());
579  cameraRotationTransformations.update();
580  gizmoEntity->setTransform(cameraRotationTransformations);
581  gizmoEntity->setNodeTransformMatrix("scale_x", rotationsMatrix);
582  gizmoEntity->setNodeTransformMatrix("scale_y", rotationsMatrix);
583  gizmoEntity->setNodeTransformMatrix("scale_z", rotationsMatrix);
584  gizmoEntity->setNodeTransformMatrix("scale_x_plane", rotationsMatrix);
585  gizmoEntity->setNodeTransformMatrix("scale_y_plane", rotationsMatrix);
586  gizmoEntity->setNodeTransformMatrix("scale_z_plane", rotationsMatrix);
587  gizmoEntity->update();
588  }
589  }
590  {
591  auto gizmoEntity = dynamic_cast<Object*>(engine->getEntity(id + ".tdme.gizmo.all"));
592  if (gizmoEntity != nullptr) {
593  cameraRotationTransformations.setTranslation(gizmoEntity->getTranslation());
594  cameraRotationTransformations.setScale(gizmoEntity->getScale());
595  cameraRotationTransformations.update();
596  gizmoEntity->setTransform(cameraRotationTransformations);
597  gizmoEntity->setNodeTransformMatrix("all_scale_x", rotationsMatrix);
598  gizmoEntity->setNodeTransformMatrix("all_scale_y", rotationsMatrix);
599  gizmoEntity->setNodeTransformMatrix("all_scale_z", rotationsMatrix);
600  gizmoEntity->setNodeTransformMatrix("scale_x_plane", rotationsMatrix);
601  gizmoEntity->setNodeTransformMatrix("scale_y_plane", rotationsMatrix);
602  gizmoEntity->setNodeTransformMatrix("scale_z_plane", rotationsMatrix);
603  gizmoEntity->update();
604  }
605  }
606 }
const Matrix4x4 & getCameraMatrix() const
Definition: Camera.h:249
Engine main class.
Definition: Engine.h:131
bool removeEntity(const string &id)
Removes an entity.
Definition: Engine.cpp:502
Camera * getCamera()
Definition: Engine.h:1071
Vector3 computeWorldCoordinateByMousePosition(int32_t mouseX, int32_t mouseY, float z)
Compute world coordinate from mouse position and z value.
Definition: Engine.h:1253
void addEntity(Entity *entity)
Adds an entity by id.
Definition: Engine.cpp:357
Entity * getEntity(const string &id)
Returns a entity by given id.
Definition: Engine.h:1175
Engine entity.
Definition: Entity.h:30
virtual const string & getId()=0
Frustum class.
Definition: Frustum.h:29
Object to be used with engine class.
Definition: Object.h:60
void setTranslation(const Vector3 &translation) override
Set translation.
Definition: Object.h:287
void setRenderPass(RenderPass renderPass) override
Set render pass.
Definition: Object.h:353
void update() override
Update transform.
Definition: Object.cpp:57
void setPickable(bool pickable) override
Set this entity pickable.
Definition: Object.h:279
void setScale(const Vector3 &scale) override
Set scale.
Definition: Object.h:295
void setFrustumCulling(bool frustumCulling) override
Set frustum culling.
Definition: Object.cpp:89
Transform which contain scale, rotations and translation.
Definition: Transform.h:29
void setTranslation(const Vector3 &translation)
Set translation.
Definition: Transform.h:64
void setScale(const Vector3 &scale)
Set scale.
Definition: Transform.h:79
const Quaternion & getRotationsQuaternion() const
Definition: Transform.h:162
virtual void update()
Computes transform matrix.
Definition: Transform.cpp:33
void addRotation(const Vector3 &axis, const float angle)
Add rotation.
Definition: Transform.h:113
Representation of a 3D model.
Definition: Model.h:35
Model node.
Definition: Node.h:32
const string & getId()
Returns id.
Definition: Node.h:89
Line segment helper functions.
Definition: LineSegment.h:16
Standard math functions.
Definition: Math.h:19
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Definition: Matrix4x4.h:225
Vector3 computeEulerAngles() const
Compute Euler angles (rotation around x, y, z axes)
Definition: Matrix4x4.h:531
Quaternion class representing quaternion mathematical structure and operations with x,...
Definition: Quaternion.h:24
Matrix4x4 computeMatrix() const
Computes a rotation matrix4x4 from this quaternion.
Definition: Quaternion.h:379
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
float getY() const
Definition: Vector3.h:117
Vector3 & setX(float x)
Sets x component.
Definition: Vector3.h:109
float getX() const
Definition: Vector3.h:100
float computeLength() const
Definition: Vector3.h:274
float getZ() const
Definition: Vector3.h:134
Vector3 & add(float scalar)
Adds a scalar.
Definition: Vector3.h:153
Vector3 & setY(float y)
Sets y component.
Definition: Vector3.h:126
float computeLengthSquared() const
Definition: Vector3.h:281
Vector3 clone() const
Clones this vector3.
Definition: Vector3.h:374
Vector3 & sub(float scalar)
Subtracts a scalar.
Definition: Vector3.h:177
Vector3 & scale(float scalar)
Scales by scalar.
Definition: Vector3.h:201
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Definition: Vector3.h:70
Vector3 & setZ(float z)
Sets z component.
Definition: Vector3.h:143
Vector3 & normalize()
Normalizes this vector3.
Definition: Vector3.h:239
Vector4 class representing vector4 mathematical structure and operations with x, y,...
Definition: Vector4.h:22
Gizmo tool for views.
Definition: Gizmo.h:31
virtual ~Gizmo()
Destructor.
Definition: Gizmo.cpp:62
void setGizmoRotation(const Transform &transform)
Set gizmo rotation.
Definition: Gizmo.cpp:542
bool determineGizmoMovement(int mouseX, int mouseY, int axisIdx, const Vector3 &axis, Vector3 &deltaMovement)
Determine gizmo movement.
Definition: Gizmo.cpp:216
void setGizmoMode(GizmoMode gizmoMode)
Set GIZMO mode.
Definition: Gizmo.h:167
array< Vector3, 3 > gizmoTranslationLastResult
Definition: Gizmo.h:79
array< bool, 3 > gizmoTranslationHandleDiffAvailable
Definition: Gizmo.h:76
bool determineGizmoDeltaTransformations(int mouseX, int mouseY, Vector3 &deltaTranslation, Vector3 &deltaRotation, Vector3 &deltaScale)
Determine GIZMO delta transform.
Definition: Gizmo.cpp:329
bool determineGizmoScale(int mouseX, int mouseY, int axisIdx, const Vector3 &axis, Vector3 &deltaScale)
Determine gizmo scale.
Definition: Gizmo.cpp:265
bool determineGizmoRotation(int mouseX, int mouseY, const array< Vector3, 4 > &vertices, const Vector3 &planeNormal, float &deltaRotation)
Determine rotation on a plane given by 4 vertices.
Definition: Gizmo.cpp:292
array< Vector3, 3 > gizmoTranslationHandleDiff
Definition: Gizmo.h:77
GizmoType getGizmoType() const
Definition: Gizmo.h:143
Vector3 computeOrthogonalGizmoCoordinate(const Vector3 &worldCoordinate)
Compute orthogonal gizmo coordinate.
Definition: Gizmo.h:89
void removeGizmo()
Remove gizmo.
Definition: Gizmo.cpp:208
void updateGizmo(const Vector3 &gizmoTranslation, const Transform &transform)
Update gizmo.
Definition: Gizmo.cpp:65
static constexpr float GIZMO_ORTHO_DEFAULT_SCALE
Definition: Gizmo.h:33
void setGizmoType(GizmoType gizmoType)
Set GIZMO type.
Definition: Gizmo.h:151
GizmoMode getGizmoMode() const
Definition: Gizmo.h:159
bool determineGizmoMode(Entity *selectedEntity, Node *selectedEntityNode)
Select GIZMO mode.
Definition: Gizmo.cpp:515
array< bool, 3 > gizmoTranslationLastResultAvailable
Definition: Gizmo.h:78
static Model * getGizmoTranslation()
Definition: Tools.cpp:626
static Model * getGizmoTranslationScale()
Definition: Tools.cpp:616
static Model * getGizmoScale()
Definition: Tools.cpp:636
static Model * getGizmoRotations()
Definition: Tools.cpp:646
static Model * getGizmoAll()
Definition: Tools.cpp:606
Console class.
Definition: Console.h:29
String tools class.
Definition: StringTools.h:22