170 lines · 5.9 KB · C++
RawDownload
////  EntityTypes.cpp//  libraries/entities/src////  Created by Brad Hefta-Gaub on 12/4/13.//  Copyright 2013 High Fidelity, Inc.//  Copyright 2023 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// #include "EntityTypes.h" #include <QtCore/QObject> #include <ByteCountCoding.h>#include <Octree.h> #include "EntityItem.h"#include "EntityItemProperties.h"#include "EntitiesLogging.h" #include "ShapeEntityItem.h"#include "ModelEntityItem.h"#include "ParticleEffectEntityItem.h"#include "ProceduralParticleEffectEntityItem.h"#include "TextEntityItem.h"#include "ImageEntityItem.h"#include "WebEntityItem.h"#include "LineEntityItem.h"#include "PolyLineEntityItem.h"#include "PolyVoxEntityItem.h"#include "GridEntityItem.h"#include "GizmoEntityItem.h"#include "LightEntityItem.h"#include "ZoneEntityItem.h"#include "MaterialEntityItem.h"#include "SoundEntityItem.h"#include "CanvasEntityItem.h"#include "EmptyEntityItem.h"#include "ScriptEntityItem.h" QMap<EntityTypes::EntityType, QString> EntityTypes::_typeToNameMap;QMap<QString, EntityTypes::EntityType> EntityTypes::_nameToTypeMap;EntityTypeFactory EntityTypes::_factories[EntityTypes::NUM_TYPES];bool EntityTypes::_factoriesInitialized = false; const QString ENTITY_TYPE_NAME_UNKNOWN = "Unknown"; // Register Entity the default implementations of entity types here...REGISTER_ENTITY_TYPE_WITH_FACTORY(Box, ShapeEntityItem::boxFactory)REGISTER_ENTITY_TYPE_WITH_FACTORY(Sphere, ShapeEntityItem::sphereFactory)REGISTER_ENTITY_TYPE(Shape)REGISTER_ENTITY_TYPE(Model)REGISTER_ENTITY_TYPE(Text)REGISTER_ENTITY_TYPE(Image)REGISTER_ENTITY_TYPE(Web)REGISTER_ENTITY_TYPE(ParticleEffect)REGISTER_ENTITY_TYPE(ProceduralParticleEffect)REGISTER_ENTITY_TYPE(Line)REGISTER_ENTITY_TYPE(PolyLine)REGISTER_ENTITY_TYPE(PolyVox)REGISTER_ENTITY_TYPE(Grid)REGISTER_ENTITY_TYPE(Gizmo)REGISTER_ENTITY_TYPE(Light)REGISTER_ENTITY_TYPE(Zone)REGISTER_ENTITY_TYPE(Material)REGISTER_ENTITY_TYPE(Sound)REGISTER_ENTITY_TYPE(Canvas)REGISTER_ENTITY_TYPE(Empty)REGISTER_ENTITY_TYPE(Script) bool EntityTypes::typeIsValid(EntityType type) {    return type > EntityType::Unknown && type <= EntityType::NUM_TYPES;} const QString& EntityTypes::getEntityTypeName(EntityType entityType) {    QMap<EntityType, QString>::iterator matchedTypeName = _typeToNameMap.find(entityType);    if (matchedTypeName != _typeToNameMap.end()) {        return matchedTypeName.value();    }    return ENTITY_TYPE_NAME_UNKNOWN;} EntityTypes::EntityType EntityTypes::getEntityTypeFromName(const QString& name) {    QMap<QString, EntityTypes::EntityType>::iterator matchedTypeName = _nameToTypeMap.find(name);    if (matchedTypeName != _nameToTypeMap.end()) {        return matchedTypeName.value();    }    if (name.size() > 0 && name[0].isLower()) {        qCDebug(entities) << "Entity types must start with an uppercase letter. Please change the type" << name;    }    return Unknown;} bool EntityTypes::registerEntityType(EntityType entityType, const char* name, EntityTypeFactory factoryMethod) {    _typeToNameMap[entityType] = name;    _nameToTypeMap[name] = entityType;    if (!_factoriesInitialized) {        memset(&_factories,0,sizeof(_factories));        _factoriesInitialized = true;    }    if (entityType >= 0 && entityType < NUM_TYPES) {        _factories[entityType] = factoryMethod;        return true;    }    return false;} EntityItemPointer EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,                                                    const EntityItemProperties& properties) {    EntityItemPointer newEntityItem = NULL;    EntityTypeFactory factory = NULL;    if (entityType >= 0 && entityType < NUM_TYPES) {        factory = _factories[entityType];    }    if (factory) {        auto mutableProperties = properties;        mutableProperties.markAllChanged();        newEntityItem = factory(entityID, mutableProperties);        newEntityItem->moveToThread(qApp->thread());    }    return newEntityItem;} void EntityTypes::extractEntityTypeAndID(const unsigned char* data, int dataLength, EntityTypes::EntityType& typeOut, QUuid& idOut) {     // Header bytes    //    object ID [16 bytes]    //    ByteCountCoded(type code) [~1 byte]    //    last edited [8 bytes]    //    ByteCountCoded(last_edited to last_updated delta) [~1-8 bytes]    //    PropertyFlags<>( everything ) [1-2 bytes]    // ~27-35 bytes...    const int MINIMUM_HEADER_BYTES = 27;     if (dataLength >= MINIMUM_HEADER_BYTES) {        int bytesRead = 0;        QByteArray originalDataBuffer = QByteArray::fromRawData((const char*)data, dataLength);         // id        QByteArray encodedID = originalDataBuffer.mid(bytesRead, NUM_BYTES_RFC4122_UUID); // maximum possible size        idOut = QUuid::fromRfc4122(encodedID);        bytesRead += encodedID.size();         // type        QByteArray encodedType = originalDataBuffer.mid(bytesRead); // maximum possible size        ByteCountCoded<quint32> typeCoder = encodedType;        encodedType = typeCoder; // determine true length        quint32 type = typeCoder;        typeOut = (EntityTypes::EntityType)type;    }} EntityItemPointer EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead) {    QUuid id;    EntityTypes::EntityType type = EntityTypes::Unknown;    extractEntityTypeAndID(data, bytesToRead, type, id);    if (type > EntityTypes::Unknown && type <= EntityTypes::NUM_TYPES) {        EntityItemID tempEntityID(id);        EntityItemProperties tempProperties;        return constructEntityItem(type, tempEntityID, tempProperties);    }    return nullptr;} EntityItemPointer EntityTypes::constructEntityItem(const QUuid& id, const EntityItemProperties& properties) {    return constructEntityItem(properties.getType(), id, properties);}