14 #ifndef hifi_RegisteredMetaTypes_h
15 #define hifi_RegisteredMetaTypes_h
17 #include <QtCore/QUuid>
18 #include <QtCore/QUrl>
21 #include <glm/glm.hpp>
22 #include <glm/gtc/quaternion.hpp>
25 #include "ShapeInfo.h"
26 #include "SharedUtil.h"
27 #include "shared/Bilateral.h"
28 #include "Transform.h"
29 #include "PhysicsCollisionGroups.h"
30 #include "StencilMaskMode.h"
35 Q_DECLARE_METATYPE(uint16_t)
36 Q_DECLARE_METATYPE(glm::vec2)
37 Q_DECLARE_METATYPE(glm::u8vec3)
38 Q_DECLARE_METATYPE(glm::vec3)
39 Q_DECLARE_METATYPE(glm::vec4)
40 Q_DECLARE_METATYPE(glm::quat)
41 Q_DECLARE_METATYPE(glm::mat4)
42 Q_DECLARE_METATYPE(QVector<float>)
43 Q_DECLARE_METATYPE(
unsigned int)
44 Q_DECLARE_METATYPE(QVector<unsigned int>)
45 Q_DECLARE_METATYPE(AACube)
46 Q_DECLARE_METATYPE(std::function<
void()>);
47 Q_DECLARE_METATYPE(std::function<QVariant()>);
71 QVariant mat4ToVariant(
const glm::mat4& mat4);
72 glm::mat4 mat4FromVariant(
const QVariant&
object,
bool& valid);
73 glm::mat4 mat4FromVariant(
const QVariant&
object);
89 QVariant vec2ToVariant(
const glm::vec2& vec2);
90 glm::vec2 vec2FromVariant(
const QVariant&
object,
bool& valid);
91 glm::vec2 vec2FromVariant(
const QVariant&
object);
113 QVariant vec3toVariant(
const glm::vec3& vec3);
114 glm::vec3 vec3FromVariant(
const QVariant &
object,
bool& valid);
115 glm::vec3 vec3FromVariant(
const QVariant &
object);
155 QVariant u8vec3toVariant(
const glm::u8vec3& vec3);
156 QVariant u8vec3ColortoVariant(
const glm::u8vec3& vec3);
157 glm::u8vec3 u8vec3FromVariant(
const QVariant &
object,
bool& valid);
158 glm::u8vec3 u8vec3FromVariant(
const QVariant &
object);
169 QVariant vec4toVariant(
const glm::vec4& vec4);
170 glm::vec4 vec4FromVariant(
const QVariant &
object,
bool& valid);
171 glm::vec4 vec4FromVariant(
const QVariant &
object);
174 QVariant quatToVariant(
const glm::quat& quat);
175 glm::quat quatFromVariant(
const QVariant &
object,
bool& isValid);
176 glm::quat quatFromVariant(
const QVariant &
object);
186 QRect qRectFromVariant(
const QVariant&
object,
bool& isValid);
187 QRect qRectFromVariant(
const QVariant&
object);
188 QVariant qRectToVariant(
const QRect& rect);
190 QRectF qRectFFromVariant(
const QVariant&
object,
bool& isValid);
191 QRectF qRectFFromVariant(
const QVariant&
object);
192 QVariant qRectFToVariant(
const QRectF& rect);
197 virtual ~MathPick() {}
198 virtual operator bool()
const = 0;
199 virtual QVariantMap toVariantMap()
const = 0;
211 class PickRay :
public MathPick {
213 PickRay() : origin(NAN), direction(NAN), unmodifiedDirection(NAN) { }
214 PickRay(
const QVariantMap& pickVariant) :
215 origin(vec3FromVariant(pickVariant[
"origin"])), direction(vec3FromVariant(pickVariant[
"direction"])),
216 unmodifiedDirection(vec3FromVariant(pickVariant[
"unmodifiedDirection"])) {}
217 PickRay(
const glm::vec3& origin,
const glm::vec3& direction) :
218 origin(origin), direction(direction), unmodifiedDirection(direction) {}
219 PickRay(
const glm::vec3& origin,
const glm::vec3& direction,
const glm::vec3& unmodifiedDirection) :
220 origin(origin), direction(direction), unmodifiedDirection(unmodifiedDirection) {}
223 glm::vec3 unmodifiedDirection;
225 operator bool()
const override {
226 return !(glm::any(glm::isnan(origin)) || glm::any(glm::isnan(direction)) || glm::any(glm::isnan(unmodifiedDirection)));
228 bool operator==(
const PickRay& other)
const {
229 return (origin == other.origin && direction == other.direction && unmodifiedDirection == other.unmodifiedDirection);
231 QVariantMap toVariantMap()
const override {
233 pickRay[
"origin"] = vec3toVariant(origin);
234 pickRay[
"direction"] = vec3toVariant(direction);
235 pickRay[
"unmodifiedDirection"] = vec3toVariant(unmodifiedDirection);
239 Q_DECLARE_METATYPE(PickRay)
252 class StylusTip :
public MathPick {
254 StylusTip() : position(NAN), velocity(NAN) {}
255 StylusTip(
const bilateral::Side& side,
const glm::vec3& tipOffset = Vectors::ZERO ,
const glm::vec3& position = Vectors::ZERO,
256 const glm::quat& orientation = Quaternions::IDENTITY,
const glm::vec3& velocity = Vectors::ZERO) :
257 side(side), tipOffset(tipOffset), position(position), orientation(orientation), velocity(velocity) {}
258 StylusTip(
const QVariantMap& pickVariant) : side(bilateral::Side(pickVariant[
"side"].toInt())), tipOffset(vec3FromVariant(pickVariant[
"tipOffset"])),
259 position(vec3FromVariant(pickVariant[
"position"])), orientation(quatFromVariant(pickVariant[
"orientation"])), velocity(vec3FromVariant(pickVariant[
"velocity"])) {}
261 bilateral::Side side { bilateral::Side::Invalid };
264 glm::quat orientation;
267 operator bool()
const override {
return side != bilateral::Side::Invalid; }
269 bool operator==(
const StylusTip& other)
const {
270 return (side == other.side && tipOffset == other.tipOffset && position == other.position && orientation == other.orientation && velocity == other.velocity);
273 QVariantMap toVariantMap()
const override {
274 QVariantMap stylusTip;
275 stylusTip[
"side"] = (int)side;
276 stylusTip[
"tipOffset"] = vec3toVariant(tipOffset);
277 stylusTip[
"position"] = vec3toVariant(position);
278 stylusTip[
"orientation"] = quatToVariant(orientation);
279 stylusTip[
"velocity"] = vec3toVariant(velocity);
296 class PickParabola :
public MathPick {
298 PickParabola() : origin(NAN), velocity(NAN), acceleration(NAN) { }
299 PickParabola(
const QVariantMap& pickVariant) : origin(vec3FromVariant(pickVariant[
"origin"])), velocity(vec3FromVariant(pickVariant[
"velocity"])), acceleration(vec3FromVariant(pickVariant[
"acceleration"])) {}
300 PickParabola(
const glm::vec3& origin,
const glm::vec3 velocity,
const glm::vec3 acceleration) : origin(origin), velocity(velocity), acceleration(acceleration) {}
303 glm::vec3 acceleration;
305 operator bool()
const override {
306 return !(glm::any(glm::isnan(origin)) || glm::any(glm::isnan(velocity)) || glm::any(glm::isnan(acceleration)));
308 bool operator==(
const PickParabola& other)
const {
309 return (origin == other.origin && velocity == other.velocity && acceleration == other.acceleration);
311 QVariantMap toVariantMap()
const override {
312 QVariantMap pickParabola;
313 pickParabola[
"origin"] = vec3toVariant(origin);
314 pickParabola[
"velocity"] = vec3toVariant(velocity);
315 pickParabola[
"acceleration"] = vec3toVariant(acceleration);
320 class CollisionRegion :
public MathPick {
322 CollisionRegion() { }
324 CollisionRegion(
const CollisionRegion& collisionRegion) :
325 loaded(collisionRegion.loaded),
326 modelURL(collisionRegion.modelURL),
327 shapeInfo(std::make_shared<ShapeInfo>()),
328 transform(collisionRegion.transform),
329 threshold(collisionRegion.threshold),
330 collisionGroup(collisionRegion.collisionGroup)
332 shapeInfo->setParams(collisionRegion.shapeInfo->getType(), collisionRegion.shapeInfo->getHalfExtents(), collisionRegion.modelURL.toString());
335 CollisionRegion(
const QVariantMap& pickVariant) {
337 if (pickVariant[
"shape"].isValid()) {
338 auto shape = pickVariant[
"shape"].toMap();
339 if (!shape.empty()) {
340 ShapeType shapeType = SHAPE_TYPE_NONE;
341 if (shape[
"shapeType"].isValid()) {
342 shapeType = ShapeInfo::getShapeTypeForName(shape[
"shapeType"].toString());
344 if (shapeType >= SHAPE_TYPE_COMPOUND && shapeType <= SHAPE_TYPE_STATIC_MESH && shape[
"modelURL"].isValid()) {
345 QString newURL = shape[
"modelURL"].toString();
346 modelURL.setUrl(newURL);
351 if (shape[
"dimensions"].isValid()) {
352 transform.setScale(vec3FromVariant(shape[
"dimensions"]));
355 shapeInfo->setParams(shapeType, transform.getScale() / 2.0f, modelURL.toString());
359 if (pickVariant[
"threshold"].isValid()) {
360 threshold = glm::max(0.0f, pickVariant[
"threshold"].toFloat());
363 if (pickVariant[
"position"].isValid()) {
364 transform.setTranslation(vec3FromVariant(pickVariant[
"position"]));
366 if (pickVariant[
"orientation"].isValid()) {
367 transform.setRotation(quatFromVariant(pickVariant[
"orientation"]));
369 if (pickVariant[
"collisionGroup"].isValid()) {
370 collisionGroup = pickVariant[
"collisionGroup"].toUInt();
398 QVariantMap toVariantMap()
const override {
399 QVariantMap collisionRegion;
402 shape[
"shapeType"] = ShapeInfo::getNameForShapeType(shapeInfo->getType());
403 shape[
"modelURL"] = modelURL.toString();
404 shape[
"dimensions"] = vec3toVariant(transform.getScale());
406 collisionRegion[
"shape"] = shape;
407 collisionRegion[
"loaded"] = loaded;
409 collisionRegion[
"threshold"] = threshold;
410 collisionRegion[
"collisionGroup"] = collisionGroup;
412 collisionRegion[
"position"] = vec3toVariant(transform.getTranslation());
413 collisionRegion[
"orientation"] = quatToVariant(transform.getRotation());
415 return collisionRegion;
418 operator bool()
const override {
419 return !std::isnan(threshold) &&
420 !(glm::any(glm::isnan(transform.getTranslation())) ||
421 glm::any(glm::isnan(transform.getRotation())) ||
422 shapeInfo->getType() == SHAPE_TYPE_NONE ||
423 collisionGroup == 0);
426 bool operator==(
const CollisionRegion& other)
const {
427 return loaded == other.loaded &&
428 threshold == other.threshold &&
429 collisionGroup == other.collisionGroup &&
430 glm::all(glm::equal(transform.getTranslation(), other.transform.getTranslation())) &&
431 glm::all(glm::equal(transform.getRotation(), other.transform.getRotation())) &&
432 glm::all(glm::equal(transform.getScale(), other.transform.getScale())) &&
433 shapeInfo->getType() == other.shapeInfo->getType() &&
434 modelURL == other.modelURL;
437 bool shouldComputeShapeInfo()
const {
438 if (!(shapeInfo->getType() == SHAPE_TYPE_HULL ||
439 (shapeInfo->getType() >= SHAPE_TYPE_COMPOUND &&
440 shapeInfo->getType() <= SHAPE_TYPE_STATIC_MESH)
445 if (collisionGroup == 0) {
449 return !shapeInfo->getPointCollection().size();
453 bool loaded {
false };
457 std::shared_ptr<ShapeInfo> shapeInfo = std::make_shared<ShapeInfo>();
459 float threshold { 0.0f };
460 uint16_t collisionGroup { USER_COLLISION_GROUP_MY_AVATAR };
463 inline void hash_combine(std::size_t& seed) {
467 template <
typename T,
typename... Rest>
468 inline void hash_combine(std::size_t& seed,
const T& v, Rest... rest) {
470 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
471 hash_combine(seed, rest...);
475 struct std::hash<bilateral::Side> {
476 size_t operator()(
const bilateral::Side& a)
const {
return std::hash<int>()((int)a); }
480 struct std::hash<glm::vec3> {
481 size_t operator()(
const glm::vec3& a)
const {
483 hash_combine(result, a.x, a.y, a.z);
489 struct std::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 std::hash<Transform> {
499 size_t operator()(
const Transform& a)
const {
501 hash_combine(result, a.getTranslation(), a.getRotation(), a.getScale());
507 struct std::hash<PickRay> {
508 size_t operator()(
const PickRay& a)
const {
510 hash_combine(result, a.origin, a.direction);
516 struct std::hash<StylusTip> {
517 size_t operator()(
const StylusTip& a)
const {
519 hash_combine(result, a.side, a.position, a.orientation, a.velocity);
525 struct std::hash<PickParabola> {
526 size_t operator()(
const PickParabola& a)
const {
528 hash_combine(result, a.origin, a.velocity, a.acceleration);
534 struct std::hash<CollisionRegion> {
535 size_t operator()(
const CollisionRegion& a)
const {
537 hash_combine(result, a.transform, (
int)a.shapeInfo->getType(), qHash(a.modelURL));
556 enum ContactEventType {
557 CONTACT_EVENT_TYPE_START,
558 CONTACT_EVENT_TYPE_CONTINUE,
559 CONTACT_EVENT_TYPE_END
564 Collision() : type(CONTACT_EVENT_TYPE_START), idA(), idB(), contactPoint(0.0f), penetration(0.0f), velocityChange(0.0f) { }
565 Collision(ContactEventType cType,
const QUuid& cIdA,
const QUuid& cIdB,
const glm::vec3& cPoint,
566 const glm::vec3& cPenetration,
const glm::vec3& velocityChange)
567 : type(cType), idA(cIdA), idB(cIdB), contactPoint(cPoint), penetration(cPenetration), velocityChange(velocityChange) { }
571 ContactEventType type;
574 glm::vec3 contactPoint;
575 glm::vec3 penetration;
576 glm::vec3 velocityChange;
578 Q_DECLARE_METATYPE(Collision)
580 class AnimationDetails {
583 AnimationDetails(QString role, QUrl url,
float fps,
float priority,
bool loop,
584 bool hold,
bool startAutomatically,
float firstFrame,
float lastFrame,
bool running,
float currentFrame,
bool allowTranslation);
592 bool startAutomatically;
597 bool allowTranslation;
599 Q_DECLARE_METATYPE(AnimationDetails);
605 using MeshPointer = std::shared_ptr<graphics::Mesh>;
621 class MeshProxy :
public QObject {
625 virtual MeshPointer getMeshPointer()
const = 0;
632 Q_INVOKABLE
virtual int getNumVertices()
const = 0;
640 Q_INVOKABLE
virtual glm::vec3 getPos(
int index)
const = 0;
641 Q_INVOKABLE
virtual glm::vec3 getPos3(
int index)
const {
return getPos(index); }
644 Q_DECLARE_METATYPE(MeshProxy*);
646 class MeshProxyList :
public QList<MeshProxy*> {};
647 Q_DECLARE_METATYPE(MeshProxyList);
654 QVector<uint32_t> vertexIndices;
658 Q_DECLARE_METATYPE(MeshFace)
659 Q_DECLARE_METATYPE(QVector<MeshFace>)
661 QVariantMap parseTexturesToMap(QString textures,
const QVariantMap& defaultTextures);
663 Q_DECLARE_METATYPE(StencilMaskMode)