14 #ifndef hifi_RegisteredMetaTypes_h
15 #define hifi_RegisteredMetaTypes_h
17 #include <QtCore/QUuid>
18 #include <QtCore/QUrl>
20 #include <glm/glm.hpp>
21 #include <glm/gtc/quaternion.hpp>
24 #include "ShapeInfo.h"
25 #include "SharedUtil.h"
26 #include "shared/Bilateral.h"
27 #include "Transform.h"
28 #include "PhysicsCollisionGroups.h"
29 #include "StencilMaskMode.h"
34 Q_DECLARE_METATYPE(uint16_t)
35 Q_DECLARE_METATYPE(glm::vec2)
36 Q_DECLARE_METATYPE(glm::u8vec3)
37 Q_DECLARE_METATYPE(glm::vec3)
38 Q_DECLARE_METATYPE(glm::vec4)
39 Q_DECLARE_METATYPE(glm::quat)
40 Q_DECLARE_METATYPE(glm::mat4)
41 Q_DECLARE_METATYPE(QVector<float>)
42 Q_DECLARE_METATYPE(
unsigned int)
43 Q_DECLARE_METATYPE(QVector<unsigned int>)
44 Q_DECLARE_METATYPE(AACube)
45 Q_DECLARE_METATYPE(std::function<
void()>);
46 Q_DECLARE_METATYPE(std::function<QVariant()>);
70 QVariant mat4ToVariant(
const glm::mat4& mat4);
71 glm::mat4 mat4FromVariant(
const QVariant&
object,
bool& valid);
72 glm::mat4 mat4FromVariant(
const QVariant&
object);
88 QVariant vec2ToVariant(
const glm::vec2& vec2);
89 glm::vec2 vec2FromVariant(
const QVariant&
object,
bool& valid);
90 glm::vec2 vec2FromVariant(
const QVariant&
object);
112 QVariant vec3toVariant(
const glm::vec3& vec3);
113 glm::vec3 vec3FromVariant(
const QVariant &
object,
bool& valid);
114 glm::vec3 vec3FromVariant(
const QVariant &
object);
154 QVariant u8vec3toVariant(
const glm::u8vec3& vec3);
155 QVariant u8vec3ColortoVariant(
const glm::u8vec3& vec3);
156 glm::u8vec3 u8vec3FromVariant(
const QVariant &
object,
bool& valid);
157 glm::u8vec3 u8vec3FromVariant(
const QVariant &
object);
168 QVariant vec4toVariant(
const glm::vec4& vec4);
169 glm::vec4 vec4FromVariant(
const QVariant &
object,
bool& valid);
170 glm::vec4 vec4FromVariant(
const QVariant &
object);
173 QVariant quatToVariant(
const glm::quat& quat);
174 glm::quat quatFromVariant(
const QVariant &
object,
bool& isValid);
175 glm::quat quatFromVariant(
const QVariant &
object);
185 QRect qRectFromVariant(
const QVariant&
object,
bool& isValid);
186 QRect qRectFromVariant(
const QVariant&
object);
187 QVariant qRectToVariant(
const QRect& rect);
189 QRectF qRectFFromVariant(
const QVariant&
object,
bool& isValid);
190 QRectF qRectFFromVariant(
const QVariant&
object);
191 QVariant qRectFToVariant(
const QRectF& rect);
196 virtual ~MathPick() {}
197 virtual operator bool()
const = 0;
198 virtual QVariantMap toVariantMap()
const = 0;
210 class PickRay :
public MathPick {
212 PickRay() : origin(NAN), direction(NAN), unmodifiedDirection(NAN) { }
213 PickRay(
const QVariantMap& pickVariant) :
214 origin(vec3FromVariant(pickVariant[
"origin"])), direction(vec3FromVariant(pickVariant[
"direction"])),
215 unmodifiedDirection(vec3FromVariant(pickVariant[
"unmodifiedDirection"])) {}
216 PickRay(
const glm::vec3& origin,
const glm::vec3& direction) :
217 origin(origin), direction(direction), unmodifiedDirection(direction) {}
218 PickRay(
const glm::vec3& origin,
const glm::vec3& direction,
const glm::vec3& unmodifiedDirection) :
219 origin(origin), direction(direction), unmodifiedDirection(unmodifiedDirection) {}
222 glm::vec3 unmodifiedDirection;
224 operator bool()
const override {
225 return !(glm::any(glm::isnan(origin)) || glm::any(glm::isnan(direction)) || glm::any(glm::isnan(unmodifiedDirection)));
227 bool operator==(
const PickRay& other)
const {
228 return (origin == other.origin && direction == other.direction && unmodifiedDirection == other.unmodifiedDirection);
230 QVariantMap toVariantMap()
const override {
232 pickRay[
"origin"] = vec3toVariant(origin);
233 pickRay[
"direction"] = vec3toVariant(direction);
234 pickRay[
"unmodifiedDirection"] = vec3toVariant(unmodifiedDirection);
238 Q_DECLARE_METATYPE(PickRay)
251 class StylusTip :
public MathPick {
253 StylusTip() : position(NAN), velocity(NAN) {}
254 StylusTip(
const bilateral::Side& side,
const glm::vec3& tipOffset = Vectors::ZERO ,
const glm::vec3& position = Vectors::ZERO,
255 const glm::quat& orientation = Quaternions::IDENTITY,
const glm::vec3& velocity = Vectors::ZERO) :
256 side(side), tipOffset(tipOffset), position(position), orientation(orientation), velocity(velocity) {}
257 StylusTip(
const QVariantMap& pickVariant) : side(bilateral::Side(pickVariant[
"side"].toInt())), tipOffset(vec3FromVariant(pickVariant[
"tipOffset"])),
258 position(vec3FromVariant(pickVariant[
"position"])), orientation(quatFromVariant(pickVariant[
"orientation"])), velocity(vec3FromVariant(pickVariant[
"velocity"])) {}
260 bilateral::Side side { bilateral::Side::Invalid };
263 glm::quat orientation;
266 operator bool()
const override {
return side != bilateral::Side::Invalid; }
268 bool operator==(
const StylusTip& other)
const {
269 return (side == other.side && tipOffset == other.tipOffset && position == other.position && orientation == other.orientation && velocity == other.velocity);
272 QVariantMap toVariantMap()
const override {
273 QVariantMap stylusTip;
274 stylusTip[
"side"] = (int)side;
275 stylusTip[
"tipOffset"] = vec3toVariant(tipOffset);
276 stylusTip[
"position"] = vec3toVariant(position);
277 stylusTip[
"orientation"] = quatToVariant(orientation);
278 stylusTip[
"velocity"] = vec3toVariant(velocity);
295 class PickParabola :
public MathPick {
297 PickParabola() : origin(NAN), velocity(NAN), acceleration(NAN) { }
298 PickParabola(
const QVariantMap& pickVariant) : origin(vec3FromVariant(pickVariant[
"origin"])), velocity(vec3FromVariant(pickVariant[
"velocity"])), acceleration(vec3FromVariant(pickVariant[
"acceleration"])) {}
299 PickParabola(
const glm::vec3& origin,
const glm::vec3 velocity,
const glm::vec3 acceleration) : origin(origin), velocity(velocity), acceleration(acceleration) {}
302 glm::vec3 acceleration;
304 operator bool()
const override {
305 return !(glm::any(glm::isnan(origin)) || glm::any(glm::isnan(velocity)) || glm::any(glm::isnan(acceleration)));
307 bool operator==(
const PickParabola& other)
const {
308 return (origin == other.origin && velocity == other.velocity && acceleration == other.acceleration);
310 QVariantMap toVariantMap()
const override {
311 QVariantMap pickParabola;
312 pickParabola[
"origin"] = vec3toVariant(origin);
313 pickParabola[
"velocity"] = vec3toVariant(velocity);
314 pickParabola[
"acceleration"] = vec3toVariant(acceleration);
319 class CollisionRegion :
public MathPick {
321 CollisionRegion() { }
323 CollisionRegion(
const CollisionRegion& collisionRegion) :
324 loaded(collisionRegion.loaded),
325 modelURL(collisionRegion.modelURL),
326 shapeInfo(std::make_shared<ShapeInfo>()),
327 transform(collisionRegion.transform),
328 threshold(collisionRegion.threshold),
329 collisionGroup(collisionRegion.collisionGroup)
331 shapeInfo->setParams(collisionRegion.shapeInfo->getType(), collisionRegion.shapeInfo->getHalfExtents(), collisionRegion.modelURL.toString());
334 CollisionRegion(
const QVariantMap& pickVariant) {
336 if (pickVariant[
"shape"].isValid()) {
337 auto shape = pickVariant[
"shape"].toMap();
338 if (!shape.empty()) {
339 ShapeType shapeType = SHAPE_TYPE_NONE;
340 if (shape[
"shapeType"].isValid()) {
341 shapeType = ShapeInfo::getShapeTypeForName(shape[
"shapeType"].toString());
343 if (shapeType >= SHAPE_TYPE_COMPOUND && shapeType <= SHAPE_TYPE_STATIC_MESH && shape[
"modelURL"].isValid()) {
344 QString newURL = shape[
"modelURL"].toString();
345 modelURL.setUrl(newURL);
350 if (shape[
"dimensions"].isValid()) {
351 transform.setScale(vec3FromVariant(shape[
"dimensions"]));
354 shapeInfo->setParams(shapeType, transform.getScale() / 2.0f, modelURL.toString());
358 if (pickVariant[
"threshold"].isValid()) {
359 threshold = glm::max(0.0f, pickVariant[
"threshold"].toFloat());
362 if (pickVariant[
"position"].isValid()) {
363 transform.setTranslation(vec3FromVariant(pickVariant[
"position"]));
365 if (pickVariant[
"orientation"].isValid()) {
366 transform.setRotation(quatFromVariant(pickVariant[
"orientation"]));
368 if (pickVariant[
"collisionGroup"].isValid()) {
369 collisionGroup = pickVariant[
"collisionGroup"].toUInt();
397 QVariantMap toVariantMap()
const override {
398 QVariantMap collisionRegion;
401 shape[
"shapeType"] = ShapeInfo::getNameForShapeType(shapeInfo->getType());
402 shape[
"modelURL"] = modelURL.toString();
403 shape[
"dimensions"] = vec3toVariant(transform.getScale());
405 collisionRegion[
"shape"] = shape;
406 collisionRegion[
"loaded"] = loaded;
408 collisionRegion[
"threshold"] = threshold;
409 collisionRegion[
"collisionGroup"] = collisionGroup;
411 collisionRegion[
"position"] = vec3toVariant(transform.getTranslation());
412 collisionRegion[
"orientation"] = quatToVariant(transform.getRotation());
414 return collisionRegion;
417 operator bool()
const override {
418 return !std::isnan(threshold) &&
419 !(glm::any(glm::isnan(transform.getTranslation())) ||
420 glm::any(glm::isnan(transform.getRotation())) ||
421 shapeInfo->getType() == SHAPE_TYPE_NONE ||
422 collisionGroup == 0);
425 bool operator==(
const CollisionRegion& other)
const {
426 return loaded == other.loaded &&
427 threshold == other.threshold &&
428 collisionGroup == other.collisionGroup &&
429 glm::all(glm::equal(transform.getTranslation(), other.transform.getTranslation())) &&
430 glm::all(glm::equal(transform.getRotation(), other.transform.getRotation())) &&
431 glm::all(glm::equal(transform.getScale(), other.transform.getScale())) &&
432 shapeInfo->getType() == other.shapeInfo->getType() &&
433 modelURL == other.modelURL;
436 bool shouldComputeShapeInfo()
const {
437 if (!(shapeInfo->getType() == SHAPE_TYPE_HULL ||
438 (shapeInfo->getType() >= SHAPE_TYPE_COMPOUND &&
439 shapeInfo->getType() <= SHAPE_TYPE_STATIC_MESH)
444 if (collisionGroup == 0) {
448 return !shapeInfo->getPointCollection().size();
452 bool loaded {
false };
456 std::shared_ptr<ShapeInfo> shapeInfo = std::make_shared<ShapeInfo>();
458 float threshold { 0.0f };
459 uint16_t collisionGroup { USER_COLLISION_GROUP_MY_AVATAR };
463 inline void hash_combine(std::size_t& seed) { }
465 template <
typename T,
typename... Rest>
466 inline void hash_combine(std::size_t& seed,
const T& v, Rest... rest) {
468 seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
469 hash_combine(seed, rest...);
473 struct hash<bilateral::Side> {
474 size_t operator()(
const bilateral::Side& a)
const {
475 return std::hash<int>()((int)a);
480 struct hash<glm::vec3> {
481 size_t operator()(
const glm::vec3& a)
const {
483 hash_combine(result, a.x, a.y, a.z);
489 struct hash<glm::quat> {
490 size_t operator()(
const glm::quat& a)
const {
492 hash_combine(result, a.x, a.y, a.z, a.w);
498 struct hash<Transform> {
499 size_t operator()(
const Transform& a)
const {
501 hash_combine(result, a.getTranslation(), a.getRotation(), a.getScale());
507 struct hash<PickRay> {
508 size_t operator()(
const PickRay& a)
const {
510 hash_combine(result, a.origin, a.direction);
516 struct hash<StylusTip> {
517 size_t operator()(
const StylusTip& a)
const {
519 hash_combine(result, a.side, a.position, a.orientation, a.velocity);
525 struct hash<PickParabola> {
526 size_t operator()(
const PickParabola& a)
const {
528 hash_combine(result, a.origin, a.velocity, a.acceleration);
534 struct hash<CollisionRegion> {
535 size_t operator()(
const CollisionRegion& a)
const {
537 hash_combine(result, a.transform, (
int)a.shapeInfo->getType(), qHash(a.modelURL));
542 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
544 struct hash<QString> {
545 size_t operator()(
const QString& a)
const {
566 enum ContactEventType {
567 CONTACT_EVENT_TYPE_START,
568 CONTACT_EVENT_TYPE_CONTINUE,
569 CONTACT_EVENT_TYPE_END
574 Collision() : type(CONTACT_EVENT_TYPE_START), idA(), idB(), contactPoint(0.0f), penetration(0.0f), velocityChange(0.0f) { }
575 Collision(ContactEventType cType,
const QUuid& cIdA,
const QUuid& cIdB,
const glm::vec3& cPoint,
576 const glm::vec3& cPenetration,
const glm::vec3& velocityChange)
577 : type(cType), idA(cIdA), idB(cIdB), contactPoint(cPoint), penetration(cPenetration), velocityChange(velocityChange) { }
581 ContactEventType type;
584 glm::vec3 contactPoint;
585 glm::vec3 penetration;
586 glm::vec3 velocityChange;
588 Q_DECLARE_METATYPE(Collision)
590 class AnimationDetails {
593 AnimationDetails(QString role, QUrl url,
float fps,
float priority,
bool loop,
594 bool hold,
bool startAutomatically,
float firstFrame,
float lastFrame,
bool running,
float currentFrame,
bool allowTranslation);
602 bool startAutomatically;
607 bool allowTranslation;
609 Q_DECLARE_METATYPE(AnimationDetails);
615 using MeshPointer = std::shared_ptr<graphics::Mesh>;
631 class MeshProxy :
public QObject {
635 virtual MeshPointer getMeshPointer()
const = 0;
642 Q_INVOKABLE
virtual int getNumVertices()
const = 0;
650 Q_INVOKABLE
virtual glm::vec3 getPos(
int index)
const = 0;
651 Q_INVOKABLE
virtual glm::vec3 getPos3(
int index)
const {
return getPos(index); }
654 Q_DECLARE_METATYPE(MeshProxy*);
656 class MeshProxyList :
public QList<MeshProxy*> {};
657 Q_DECLARE_METATYPE(MeshProxyList);
666 QVector<uint32_t> vertexIndices;
670 Q_DECLARE_METATYPE(MeshFace)
671 Q_DECLARE_METATYPE(QVector<MeshFace>)
673 QVariantMap parseTexturesToMap(QString textures,
const QVariantMap& defaultTextures);
675 Q_DECLARE_METATYPE(StencilMaskMode)