176 lines · 9.4 KB · C
RawDownload
////  EntityTypes.h//  libraries/entities/src////  Created by Brad Hefta-Gaub on December 4th, 2013.//  Copyright 2013 High Fidelity, Inc.//  Copyright 2023-2025 Overte e.V.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #ifndef hifi_EntityTypes_h#define hifi_EntityTypes_h #include <memory> #include <QHash>#include <QString> #include "EntitiesLogging.h" class EntityItem;using EntityItemPointer = std::shared_ptr<EntityItem>;using EntityItemWeakPointer = std::weak_ptr<EntityItem>; inline uint qHash(const EntityItemPointer& a, uint seed) {    return qHash(a.get(), seed);} class EntityItemID;class EntityItemProperties;class ReadBitstreamToTreeParams; typedef EntityItemPointer (*EntityTypeFactory)(const EntityItemID& entityID, const EntityItemProperties& properties); class EntityTypes {public:    /*@jsdoc     * <p>An entity may be one of the following types:</p>     * <table>     *   <thead>     *     <tr><th>Value</th><th>Description</th><th>Properties</th></tr>     *   </thead>     *   <tbody>     *     <tr><td><code>"Shape"</code></td><td>A basic entity such as a cube.     *       See also, the <code>"Box"</code> and <code>"Sphere"</code> entity types.</td>     *       <td>{@link Entities.EntityProperties-Shape|EntityProperties-Shape}</td></tr>     *     <tr><td><code>"Box"</code></td><td>A rectangular prism. This is a synonym of <code>"Shape"</code> for the case     *       where the entity's <code>shape</code> property value is <code>"Cube"</code>.     *       <p>If an entity is created with its <code>type</code>      *       set to <code>"Box"</code> it will always be created with a <code>shape</code> property value of      *       <code>"Cube"</code>. If an entity of type <code>Shape</code> or <code>Sphere</code> has its <code>shape</code> set      *       to <code>"Cube"</code> then its <code>type</code> will be reported as <code>"Box"</code>.</p></td>     *       <td>{@link Entities.EntityProperties-Box|EntityProperties-Box}</td></tr>     *     <tr><td><code>"Sphere"</code></td><td>A sphere. This is a synonym of <code>"Shape"</code> for the case     *       where the entity's <code>shape</code> property value is <code>"Sphere"</code>.     *       <p>If an entity is created with its <code>type</code>     *       set to <code>"Sphere"</code> it will always be created with a <code>shape</code> property value of     *       <code>"Sphere"</code>. If an entity of type <code>Box</code> or <code>Shape</code> has its <code>shape</code> set     *       to <code>"Sphere"</code> then its <code>type</code> will be reported as <code>"Sphere"</code>.</td>     *       <td>{@link Entities.EntityProperties-Sphere|EntityProperties-Sphere}</td></tr>     *     <tr><td><code>"Model"</code></td><td>A mesh model from a glTF, VRM, FBX, or OBJ file.</td>     *       <td>{@link Entities.EntityProperties-Model|EntityProperties-Model}</td></tr>     *     <tr><td><code>"Text"</code></td><td>A pane of text oriented in space.</td>     *       <td>{@link Entities.EntityProperties-Text|EntityProperties-Text}</td></tr>     *     <tr><td><code>"Image"</code></td><td>An image oriented in space.</td>     *       <td>{@link Entities.EntityProperties-Image|EntityProperties-Image}</td></tr>     *     <tr><td><code>"Web"</code></td><td>A browsable web page.</td>     *       <td>{@link Entities.EntityProperties-Web|EntityProperties-Web}</td></tr>     *     <tr><td><code>"ParticleEffect"</code></td><td>A particle system that can be used to simulate things such as fire,      *       smoke, snow, magic spells, etc.</td>     *       <td>{@link Entities.EntityProperties-ParticleEffect|EntityProperties-ParticleEffect}</td></tr>     *     <tr><td><code>"ProceduralParticleEffect"</code></td><td>A GPU particle system with custom update and rendering that can     *       be used to simulate things such as fire, smoke, snow, magic spells, etc.</td>     *       <td>{@link Entities.EntityProperties-ProceduralParticleEffect|EntityProperties-ProceduralParticleEffect}</td></tr>     *     <tr><td><code>"Line"</code></td><td>A sequence of one or more simple straight lines.</td>     *       <td>{@link Entities.EntityProperties-Line|EntityProperties-Line}</td></tr>     *     <tr><td><code>"PolyLine"</code></td><td>A sequence of one or more textured straight lines.</td>     *       <td>{@link Entities.EntityProperties-PolyLine|EntityProperties-PolyLine}</td></tr>     *     <tr><td><code>"PolyVox"</code></td><td>A set of textured voxels.</td>     *       <td>{@link Entities.EntityProperties-PolyVox|EntityProperties-PolyVox}</td></tr>     *     <tr><td><code>"Grid"</code></td><td>A grid of lines in a plane.</td>     *       <td>{@link Entities.EntityProperties-Grid|EntityProperties-Grid}</td></tr>     *     <tr><td><code>"Gizmo"</code></td><td>A gizmo intended for UI.</td>     *       <td>{@link Entities.EntityProperties-Gizmo|EntityProperties-Gizmo}</td></tr>     *     <tr><td><code>"Light"</code></td><td>A local lighting effect.</td>     *       <td>{@link Entities.EntityProperties-Light|EntityProperties-Light}</td></tr>     *     <tr><td><code>"Zone"</code></td><td>A volume of lighting effects and avatar permissions.</td>     *       <td>{@link Entities.EntityProperties-Zone|EntityProperties-Zone}</td></tr>     *     <tr><td><code>"Material"</code></td><td>Modifies the existing materials on entities and avatars.</td>     *       <td>{@link Entities.EntityProperties-Material|EntityProperties-Material}</td></tr>     *     <tr><td><code>"Sound"</code></td><td>Plays a sound.</td>     *       <td>{@link Entities.EntityProperties-Sound|EntityProperties-Sound}</td></tr>     *     <tr><td><code>"Canvas"</code></td><td>A runtime scriptable image.</td>     *       <td>{@link Entities.EntityProperties-Canvas|EntityProperties-Canvas}</td></tr>     *     <tr><td><code>"Empty"</code></td><td>Invisible, intangible entity that has no special behavior.</td>     *       <td>{@link Entities.EntityProperties-Empty|EntityProperties-Empty}</td></tr>     *     <tr><td><code>"Script"</code></td><td>Starts an entity script on its parent.</td>     *       <td>{@link Entities.EntityProperties-Script|EntityProperties-Script}</td></tr>     *   </tbody>     * </table>     * @typedef {string} Entities.EntityType     */    typedef enum EntityType_t {        Unknown,        Box,        Sphere,        Shape,        Model,        Text,        Image,        Web,        ParticleEffect,        ProceduralParticleEffect,        Line,        PolyLine,        PolyVox,        Grid,        Gizmo,        Light,        Zone,        Material,        Sound,        Canvas,        Empty,        Script,        NUM_TYPES    } EntityType;     static bool typeIsValid(EntityType type);    static const QString& getEntityTypeName(EntityType entityType);    static EntityTypes::EntityType getEntityTypeFromName(const QString& name);    static bool registerEntityType(EntityType entityType, const char* name, EntityTypeFactory factoryMethod);    static void extractEntityTypeAndID(const unsigned char* data, int dataLength, EntityTypes::EntityType& typeOut, QUuid& idOut);    static EntityItemPointer constructEntityItem(EntityType entityType, const EntityItemID& entityID, const EntityItemProperties& properties);    static EntityItemPointer constructEntityItem(const unsigned char* data, int bytesToRead);    static EntityItemPointer constructEntityItem(const QUuid& id, const EntityItemProperties& properties); private:    static QMap<EntityType, QString> _typeToNameMap;    static QMap<QString, EntityTypes::EntityType> _nameToTypeMap;    static EntityTypeFactory _factories[NUM_TYPES];    static bool _factoriesInitialized;};  /// Macro for registering entity types. Make sure to add an element to the EntityType enum with your name, and your class should be/// named NameEntityItem and must of a static method called factory that takes an EnityItemID, and EntityItemProperties and return a newly/// constructed (heap allocated) instance of your type. e.g. The following prototype://        static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);#define REGISTER_ENTITY_TYPE(x) bool x##Registration = \            EntityTypes::registerEntityType(EntityTypes::x, #x, x##EntityItem::factory);  struct EntityRegistrationChecker {    EntityRegistrationChecker(bool result, const char* debugMessage) {        if (!result) {            qCDebug(entities) << debugMessage;        }    }}; /// Macro for registering entity types with an overloaded factory. Like using the REGISTER_ENTITY_TYPE macro: Make sure to add/// an element to the EntityType enum with your name. But unlike  REGISTER_ENTITY_TYPE, your class can be named anything/// so long as you provide a static method passed to the macro, that takes an EnityItemID, and EntityItemProperties and /// returns a newly constructed (heap allocated) instance of your type. e.g. The following prototype://        static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);#define REGISTER_ENTITY_TYPE_WITH_FACTORY(x,y) static bool x##Registration = \            EntityTypes::registerEntityType(EntityTypes::x, #x, y); \            EntityRegistrationChecker x##RegistrationChecker( \                x##Registration, \                "UNEXPECTED: REGISTER_ENTITY_TYPE_WITH_FACTORY(" #x "," #y ") FAILED.!");  #endif // hifi_EntityTypes_h