mirror of
https://github.com/overte-org/overte.git
synced 2025-04-18 07:56:25 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into blue
This commit is contained in:
commit
f38fa14a39
35 changed files with 311 additions and 458 deletions
|
@ -30,6 +30,8 @@
|
|||
#include <UUID.h>
|
||||
#include <WebSocketServerClass.h>
|
||||
|
||||
#include <EntityScriptClient.h> // for EntityScriptServerServices
|
||||
|
||||
#include "EntityScriptServerLogging.h"
|
||||
#include "../entities/AssignmentParentFinder.h"
|
||||
|
||||
|
@ -68,6 +70,9 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
DependencyManager::set<ScriptCache>();
|
||||
DependencyManager::set<ScriptEngines>(ScriptEngine::ENTITY_SERVER_SCRIPT);
|
||||
|
||||
DependencyManager::set<EntityScriptServerServices>();
|
||||
|
||||
|
||||
// Needed to ensure the creation of the DebugDraw instance on the main thread
|
||||
DebugDraw::getInstance();
|
||||
|
||||
|
@ -583,6 +588,7 @@ void EntityScriptServer::aboutToFinish() {
|
|||
// cleanup the AudioInjectorManager (and any still running injectors)
|
||||
DependencyManager::destroy<AudioInjectorManager>();
|
||||
DependencyManager::destroy<ScriptEngines>();
|
||||
DependencyManager::destroy<EntityScriptServerServices>();
|
||||
|
||||
// cleanup codec & encoder
|
||||
if (_codec && _encoder) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// interface/src/ui/overlays
|
||||
//
|
||||
// Created by Zander Otavka on 8/7/15.
|
||||
// Modified by Daniela Fontes on 24/10/17.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
|
@ -13,6 +14,7 @@
|
|||
|
||||
#include <Application.h>
|
||||
#include <Transform.h>
|
||||
#include "avatar/AvatarManager.h"
|
||||
|
||||
void Billboardable::setProperties(const QVariantMap& properties) {
|
||||
auto isFacingAvatar = properties["isFacingAvatar"];
|
||||
|
@ -32,10 +34,11 @@ bool Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offse
|
|||
if (isFacingAvatar()) {
|
||||
glm::vec3 billboardPos = transform.getTranslation();
|
||||
glm::vec3 cameraPos = qApp->getCamera().getPosition();
|
||||
glm::vec3 look = cameraPos - billboardPos;
|
||||
float elevation = -asinf(look.y / glm::length(look));
|
||||
float azimuth = atan2f(look.x, look.z);
|
||||
glm::quat rotation(glm::vec3(elevation, azimuth, 0));
|
||||
// use the referencial from the avatar, y isn't always up
|
||||
glm::vec3 avatarUP = DependencyManager::get<AvatarManager>()->getMyAvatar()->getOrientation()*Vectors::UP;
|
||||
|
||||
glm::quat rotation(conjugate(toQuat(glm::lookAt(billboardPos, cameraPos, avatarUP))));
|
||||
|
||||
transform.setRotation(rotation);
|
||||
transform.postRotate(offsetRotation);
|
||||
return true;
|
||||
|
|
|
@ -50,7 +50,9 @@ void EntityRenderer::initEntityRenderers() {
|
|||
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyVox, RenderablePolyVoxEntityItem::factory)
|
||||
}
|
||||
|
||||
|
||||
const Transform& EntityRenderer::getModelTransform() const {
|
||||
return _modelTransform;
|
||||
}
|
||||
|
||||
void EntityRenderer::makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
|
|
@ -105,8 +105,10 @@ protected:
|
|||
template<typename T>
|
||||
std::shared_ptr<T> asTypedEntity() { return std::static_pointer_cast<T>(_entity); }
|
||||
|
||||
|
||||
static void makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters);
|
||||
static std::function<bool()> _entitiesShouldFadeFunction;
|
||||
const Transform& getModelTransform() const;
|
||||
|
||||
SharedSoundPointer _collisionSound;
|
||||
QUuid _changeHandlerId;
|
||||
|
@ -114,7 +116,6 @@ protected:
|
|||
quint64 _fadeStartTime{ usecTimestampNow() };
|
||||
bool _isFading{ _entitiesShouldFadeFunction() };
|
||||
bool _prevIsTransparent { false };
|
||||
Transform _modelTransform;
|
||||
Item::Bound _bound;
|
||||
bool _visible { false };
|
||||
bool _moving { false };
|
||||
|
@ -123,6 +124,10 @@ protected:
|
|||
|
||||
|
||||
private:
|
||||
// The base class relies on comparing the model transform to the entity transform in order
|
||||
// to trigger an update, so the member must not be visible to derived classes as a modifiable
|
||||
// transform
|
||||
Transform _modelTransform;
|
||||
// The rendering code only gets access to the entity in very specific circumstances
|
||||
// i.e. to see if the rendering code needs to update because of a change in state of the
|
||||
// entity. This forces all the rendering code itself to be independent of the entity
|
||||
|
|
|
@ -49,9 +49,10 @@ void LineEntityRenderer::doRender(RenderArgs* args) {
|
|||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
const auto& modelTransform = getModelTransform();
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(_modelTransform.getTranslation());
|
||||
transform.setRotation(_modelTransform.getRotation());
|
||||
transform.setTranslation(modelTransform.getTranslation());
|
||||
transform.setRotation(modelTransform.getRotation());
|
||||
batch.setModelTransform(transform);
|
||||
if (_linePoints.size() > 1) {
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
|
||||
|
|
|
@ -1311,7 +1311,7 @@ void ModelEntityRenderer::doRender(RenderArgs* args) {
|
|||
if (!model || (model && model->didVisualGeometryRequestFail())) {
|
||||
static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
batch.setModelTransform(_modelTransform); // we want to include the scale as well
|
||||
batch.setModelTransform(getModelTransform()); // we want to include the scale as well
|
||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(args, batch, greenColor);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -251,12 +251,13 @@ void ParticleEffectEntityRenderer::stepSimulation() {
|
|||
});
|
||||
|
||||
if (_emitting && particleProperties.emitting()) {
|
||||
const auto& modelTransform = getModelTransform();
|
||||
uint64_t emitInterval = particleProperties.emitIntervalUsecs();
|
||||
if (emitInterval > 0 && interval >= _timeUntilNextEmit) {
|
||||
auto timeRemaining = interval;
|
||||
while (timeRemaining > _timeUntilNextEmit) {
|
||||
// emit particle
|
||||
_cpuParticles.push_back(createParticle(now, _modelTransform, particleProperties));
|
||||
_cpuParticles.push_back(createParticle(now, modelTransform, particleProperties));
|
||||
_timeUntilNextEmit = emitInterval;
|
||||
if (emitInterval < timeRemaining) {
|
||||
timeRemaining -= emitInterval;
|
||||
|
@ -315,7 +316,7 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) {
|
|||
// In trail mode, the particles are created in world space.
|
||||
// so we only set a transform if they're not in trail mode
|
||||
if (!_particleProperties.emission.shouldTrail) {
|
||||
transform = _modelTransform;
|
||||
transform = getModelTransform();
|
||||
transform.setScale(vec3(1));
|
||||
}
|
||||
batch.setModelTransform(transform);
|
||||
|
|
|
@ -76,6 +76,14 @@ bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_shape != entity->getShape()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_dimensions != entity->getDimensions()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -93,12 +101,13 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
_position = entity->getPosition();
|
||||
_dimensions = entity->getDimensions();
|
||||
_orientation = entity->getOrientation();
|
||||
_renderTransform = getModelTransform();
|
||||
|
||||
if (_shape == entity::Sphere) {
|
||||
_modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
_renderTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
}
|
||||
|
||||
_modelTransform.postScale(_dimensions);
|
||||
_renderTransform.postScale(_dimensions);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -133,7 +142,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
glm::vec4 outColor;
|
||||
withReadLock([&] {
|
||||
geometryShape = MAPPING[_shape];
|
||||
batch.setModelTransform(_modelTransform); // use a transform with scale, rotation, registration point and translation
|
||||
batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation
|
||||
outColor = _color;
|
||||
if (_procedural.isReady()) {
|
||||
_procedural.prepare(batch, _position, _dimensions, _orientation);
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
|
||||
Procedural _procedural;
|
||||
QString _lastUserData;
|
||||
Transform _renderTransform;
|
||||
entity::Shape _shape { entity::Sphere };
|
||||
glm::vec4 _color;
|
||||
glm::vec3 _position;
|
||||
|
|
|
@ -93,10 +93,11 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
|||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
|
||||
auto transformToTopLeft = _modelTransform;
|
||||
const auto& modelTransform = getModelTransform();
|
||||
auto transformToTopLeft = modelTransform;
|
||||
if (_faceCamera) {
|
||||
//rotate about vertical to face the camera
|
||||
glm::vec3 dPosition = args->getViewFrustum().getPosition() - _modelTransform.getTranslation();
|
||||
glm::vec3 dPosition = args->getViewFrustum().getPosition() - modelTransform.getTranslation();
|
||||
// If x and z are 0, atan(x, z) is undefined, so default to 0 degrees
|
||||
float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z);
|
||||
glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f));
|
||||
|
|
|
@ -139,8 +139,8 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
|
||||
glm::vec2 windowSize = getWindowSize(entity);
|
||||
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
||||
|
||||
_modelTransform.postScale(entity->getDimensions());
|
||||
_renderTransform = getModelTransform();
|
||||
_renderTransform.postScale(entity->getDimensions());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
withReadLock([&] {
|
||||
batch.setModelTransform(_modelTransform);
|
||||
batch.setModelTransform(_renderTransform);
|
||||
});
|
||||
batch.setResourceTexture(0, _texture);
|
||||
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||
|
|
|
@ -62,6 +62,7 @@ private:
|
|||
uint16_t _lastDPI;
|
||||
QTimer _timer;
|
||||
uint64_t _lastRenderTime { 0 };
|
||||
Transform _renderTransform;
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
|
|
@ -112,6 +112,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
// Do we need to allocate the light in the stage ?
|
||||
if (LightStage::isIndexInvalid(_sunIndex)) {
|
||||
_sunIndex = _stage->addLight(_sunLight);
|
||||
_shadowIndex = _stage->addShadow(_sunIndex);
|
||||
} else {
|
||||
_stage->updateLightArrayBuffer(_sunIndex);
|
||||
}
|
||||
|
@ -248,7 +249,8 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
|||
|
||||
void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||
if (entity->getShapeType() == SHAPE_TYPE_SPHERE) {
|
||||
_modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
_renderTransform = getModelTransform();
|
||||
_renderTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ private:
|
|||
ComponentMode _hazeMode{ COMPONENT_MODE_INHERIT };
|
||||
|
||||
indexed_container::Index _sunIndex{ LightStage::INVALID_INDEX };
|
||||
indexed_container::Index _shadowIndex{ LightStage::INVALID_INDEX };
|
||||
indexed_container::Index _ambientIndex{ LightStage::INVALID_INDEX };
|
||||
|
||||
BackgroundStagePointer _backgroundStage;
|
||||
|
@ -119,6 +120,7 @@ private:
|
|||
bool _validSkyboxTexture{ false };
|
||||
|
||||
QString _proceduralUserData;
|
||||
Transform _renderTransform;
|
||||
};
|
||||
|
||||
} } // namespace
|
||||
|
|
|
@ -355,14 +355,6 @@ int EntityItem::expectedBytes() {
|
|||
|
||||
// clients use this method to unpack FULL updates from entity-server
|
||||
int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) {
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) {
|
||||
|
||||
// NOTE: This shouldn't happen. The only versions of the bit stream that didn't support split mtu buffers should
|
||||
// be handled by the model subclass and shouldn't call this routine.
|
||||
qCDebug(entities) << "EntityItem::readEntityDataFromBuffer()... "
|
||||
"ERROR CASE...args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU";
|
||||
return 0;
|
||||
}
|
||||
setSourceUUID(args.sourceUUID);
|
||||
|
||||
args.entitiesPerPacket++;
|
||||
|
@ -588,34 +580,32 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
|
||||
// Newer bitstreams will have a last simulated and a last updated value
|
||||
quint64 lastSimulatedFromBufferAdjusted = now;
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME) {
|
||||
// last simulated is stored as ByteCountCoded delta from lastEdited
|
||||
quint64 simulatedDelta;
|
||||
parser.readCompressedCount(simulatedDelta);
|
||||
// last simulated is stored as ByteCountCoded delta from lastEdited
|
||||
quint64 simulatedDelta;
|
||||
parser.readCompressedCount(simulatedDelta);
|
||||
#ifdef VALIDATE_ENTITY_ITEM_PARSER
|
||||
{
|
||||
QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
|
||||
ByteCountCoded<quint64> simulatedDeltaCoder = encodedSimulatedDelta;
|
||||
quint64 simulatedDelta2 = simulatedDeltaCoder;
|
||||
Q_ASSERT(simulatedDelta2 == simulatedDelta);
|
||||
encodedSimulatedDelta = simulatedDeltaCoder; // determine true length
|
||||
dataAt += encodedSimulatedDelta.size();
|
||||
bytesRead += encodedSimulatedDelta.size();
|
||||
Q_ASSERT(parser.offset() == (unsigned int) bytesRead);
|
||||
}
|
||||
{
|
||||
QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
|
||||
ByteCountCoded<quint64> simulatedDeltaCoder = encodedSimulatedDelta;
|
||||
quint64 simulatedDelta2 = simulatedDeltaCoder;
|
||||
Q_ASSERT(simulatedDelta2 == simulatedDelta);
|
||||
encodedSimulatedDelta = simulatedDeltaCoder; // determine true length
|
||||
dataAt += encodedSimulatedDelta.size();
|
||||
bytesRead += encodedSimulatedDelta.size();
|
||||
Q_ASSERT(parser.offset() == (unsigned int) bytesRead);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (overwriteLocalData) {
|
||||
lastSimulatedFromBufferAdjusted = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that
|
||||
if (lastSimulatedFromBufferAdjusted > now) {
|
||||
lastSimulatedFromBufferAdjusted = now;
|
||||
}
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << " _lastEdited:" << debugTime(_lastEdited, now);
|
||||
qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now);
|
||||
qCDebug(entities) << " lastSimulatedFromBufferAdjusted:" << debugTime(lastSimulatedFromBufferAdjusted, now);
|
||||
#endif
|
||||
if (overwriteLocalData) {
|
||||
lastSimulatedFromBufferAdjusted = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that
|
||||
if (lastSimulatedFromBufferAdjusted > now) {
|
||||
lastSimulatedFromBufferAdjusted = now;
|
||||
}
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << " _lastEdited:" << debugTime(_lastEdited, now);
|
||||
qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now);
|
||||
qCDebug(entities) << " lastSimulatedFromBufferAdjusted:" << debugTime(lastSimulatedFromBufferAdjusted, now);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
|
@ -817,20 +807,16 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, updateLocked);
|
||||
READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData);
|
||||
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_MARKETPLACE_ID) {
|
||||
READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
||||
}
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES) {
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_NAME, QString, setItemName);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_DESCRIPTION, QString, setItemDescription);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_CATEGORIES, QString, setItemCategories);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_ARTIST, QString, setItemArtist);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_LICENSE, QString, setItemLicense);
|
||||
READ_ENTITY_PROPERTY(PROP_LIMITED_RUN, quint32, setLimitedRun);
|
||||
READ_ENTITY_PROPERTY(PROP_EDITION_NUMBER, quint32, setEditionNumber);
|
||||
READ_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, quint32, setEntityInstanceNumber);
|
||||
READ_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, QString, setCertificateID);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_NAME, QString, setItemName);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_DESCRIPTION, QString, setItemDescription);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_CATEGORIES, QString, setItemCategories);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_ARTIST, QString, setItemArtist);
|
||||
READ_ENTITY_PROPERTY(PROP_ITEM_LICENSE, QString, setItemLicense);
|
||||
READ_ENTITY_PROPERTY(PROP_LIMITED_RUN, quint32, setLimitedRun);
|
||||
READ_ENTITY_PROPERTY(PROP_EDITION_NUMBER, quint32, setEditionNumber);
|
||||
READ_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, quint32, setEntityInstanceNumber);
|
||||
READ_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, QString, setCertificateID);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
|
||||
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
|
||||
|
@ -858,10 +844,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
// NOTE: we had a bad version of the stream that we added stream data after the subclass. We can attempt to recover
|
||||
// by doing this parsing here... but it's not likely going to fully recover the content.
|
||||
//
|
||||
// TODO: Remove this code once we've sufficiently migrated content past this damaged version
|
||||
if (args.bitstreamVersion == VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED) {
|
||||
READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
||||
}
|
||||
|
||||
if (overwriteLocalData && (getDirtyFlags() & (Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES))) {
|
||||
// NOTE: This code is attempting to "repair" the old data we just got from the server to make it more
|
||||
|
|
|
@ -50,6 +50,10 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
|
|||
connect(nodeList.data(), &NodeList::canRezCertifiedChanged, this, &EntityScriptingInterface::canRezCertifiedChanged);
|
||||
connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged);
|
||||
connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged);
|
||||
|
||||
|
||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
||||
|
@ -571,6 +575,48 @@ void EntityScriptingInterface::callEntityServerMethod(QUuid id, const QString& m
|
|||
DependencyManager::get<EntityScriptClient>()->callEntityServerMethod(id, method, params);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
auto scriptServerServices = DependencyManager::get<EntityScriptServerServices>();
|
||||
|
||||
// this won't be available on clients
|
||||
if (scriptServerServices) {
|
||||
scriptServerServices->callEntityClientMethod(clientSessionID, entityID, method, params);
|
||||
} else {
|
||||
qWarning() << "Entities.callEntityClientMethod() not allowed in client";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
||||
|
||||
if (entityScriptServer == senderNode) {
|
||||
auto entityID = QUuid::fromRfc4122(receivedMessage->read(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
auto method = receivedMessage->readString();
|
||||
|
||||
quint16 paramCount;
|
||||
receivedMessage->readPrimitive(¶mCount);
|
||||
|
||||
QStringList params;
|
||||
for (int param = 0; param < paramCount; param++) {
|
||||
auto paramString = receivedMessage->readString();
|
||||
params << paramString;
|
||||
}
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
|
|
|
@ -189,12 +189,15 @@ public slots:
|
|||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Call a method on an entity. Allows a script to call a method on an entity's script.
|
||||
* The method will execute in the entity script engine. If the entity does not have an
|
||||
* entity script or the method does not exist, this call will have no effect.
|
||||
* If it is running an entity script (specified by the `script` property)
|
||||
* Call a method on an entity in the same context as this function is called. Allows a script
|
||||
* to call a method on an entity's script. The method will execute in the entity script engine.
|
||||
* If the entity does not have an entity script or the method does not exist, this call will
|
||||
* have no effect. If it is running an entity script (specified by the `script` property)
|
||||
* and it exposes a property with the specified name `method`, it will be called
|
||||
* using `params` as the list of arguments.
|
||||
* using `params` as the list of arguments. If this is called within an entity script, the
|
||||
* method will be executed on the client in the entity script engine in which it was called. If
|
||||
* this is called in an entity server script, the method will be executed on the entity server
|
||||
* script engine.
|
||||
*
|
||||
* @function Entities.callEntityMethod
|
||||
* @param {EntityID} entityID The ID of the entity to call the method on.
|
||||
|
@ -218,6 +221,21 @@ public slots:
|
|||
*/
|
||||
Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||
|
||||
/**jsdoc
|
||||
* Call a client method on an entity on a specific client node. Allows a server entity script to call a
|
||||
* method on an entity's client script for a particular client. The method will execute in the entity script
|
||||
* engine on that single client. If the entity does not have an entity script or the method does not exist, or
|
||||
* the client is not connected to the domain, or you attempt to make this call outside of the entity server
|
||||
* script, this call will have no effect.
|
||||
*
|
||||
* @function Entities.callEntityClientMethod
|
||||
* @param {SessionID} clientSessionID The session ID of the client to call the method on.
|
||||
* @param {EntityID} entityID The ID of the entity to call the method on.
|
||||
* @param {string} method The name of the method to call.
|
||||
* @param {string[]} params The list of parameters to call the specified method with.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||
|
||||
/**jsdoc
|
||||
* finds the closest model to the center point, within the radius
|
||||
* will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||
|
@ -447,6 +465,10 @@ protected:
|
|||
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||
function(_entitiesScriptEngine);
|
||||
};
|
||||
|
||||
private slots:
|
||||
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
||||
|
||||
private:
|
||||
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);
|
||||
bool polyVoxWorker(QUuid entityID, std::function<bool(PolyVoxEntityItem&)> actor);
|
||||
|
|
|
@ -89,8 +89,6 @@ public:
|
|||
// own definition. Implement these to allow your octree based server to support editing
|
||||
virtual bool getWantSVOfileVersions() const override { return true; }
|
||||
virtual PacketType expectedDataPacketType() const override { return PacketType::EntityData; }
|
||||
virtual bool canProcessVersion(PacketVersion thisVersion) const override
|
||||
{ return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; }
|
||||
virtual bool handlesEditPacketType(PacketType packetType) const override;
|
||||
void fixupTerseEditLogging(EntityItemProperties& properties, QList<QString>& changedProperties);
|
||||
virtual int processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength,
|
||||
|
@ -111,9 +109,6 @@ public:
|
|||
virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const override;
|
||||
virtual bool mustIncludeAllChildData() const override { return false; }
|
||||
|
||||
virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const override
|
||||
{ return thisVersion >= VERSION_ENTITIES_HAS_FILE_BREAKS; }
|
||||
|
||||
virtual void update() override { update(true); }
|
||||
|
||||
void update(bool simulate);
|
||||
|
|
|
@ -102,12 +102,6 @@ EntityItemPointer EntityTypes::constructEntityItem(EntityType entityType, const
|
|||
EntityItemPointer EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead,
|
||||
ReadBitstreamToTreeParams& args) {
|
||||
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) {
|
||||
EntityItemID tempEntityID;
|
||||
EntityItemProperties tempProperties;
|
||||
return constructEntityItem(Model, tempEntityID, tempProperties);
|
||||
}
|
||||
|
||||
// Header bytes
|
||||
// object ID [16 bytes]
|
||||
// ByteCountCoded(type code) [~1 byte]
|
||||
|
|
|
@ -175,35 +175,12 @@ int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES) {
|
||||
READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight);
|
||||
|
||||
// _diffuseColor has been renamed to _color
|
||||
READ_ENTITY_PROPERTY(PROP_DIFFUSE_COLOR, rgbColor, setColor);
|
||||
|
||||
// Ambient and specular color are from an older format and are no longer supported.
|
||||
// Their values will be ignored.
|
||||
READ_ENTITY_PROPERTY(PROP_AMBIENT_COLOR_UNUSED, rgbColor, setIgnoredColor);
|
||||
READ_ENTITY_PROPERTY(PROP_SPECULAR_COLOR_UNUSED, rgbColor, setIgnoredColor);
|
||||
|
||||
// _constantAttenuation has been renamed to _intensity
|
||||
READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity);
|
||||
|
||||
// Linear and quadratic attenuation are from an older format and are no longer supported.
|
||||
// Their values will be ignored.
|
||||
READ_ENTITY_PROPERTY(PROP_LINEAR_ATTENUATION_UNUSED, float, setIgnoredAttenuation);
|
||||
READ_ENTITY_PROPERTY(PROP_QUADRATIC_ATTENUATION_UNUSED, float, setIgnoredAttenuation);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent);
|
||||
READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight);
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity);
|
||||
READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent);
|
||||
READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff);
|
||||
READ_ENTITY_PROPERTY(PROP_FALLOFF_RADIUS, float, setFalloffRadius);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight);
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity);
|
||||
READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent);
|
||||
READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff);
|
||||
READ_ENTITY_PROPERTY(PROP_FALLOFF_RADIUS, float, setFalloffRadius);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
|
|
@ -111,38 +111,19 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL);
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_HAS_COLLISION_MODEL) {
|
||||
setCompoundShapeURL("");
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
||||
}
|
||||
|
||||
// Because we're using AnimationLoop which will reset the frame index if you change it's running state
|
||||
// we want to read these values in the order they appear in the buffer, but call our setters in an
|
||||
// order that allows AnimationLoop to preserve the correct frame rate.
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) {
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setAnimationURL);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationCurrentFrame);
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
||||
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) {
|
||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings);
|
||||
} else {
|
||||
int bytesFromAnimation;
|
||||
withWriteLock([&] {
|
||||
// Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer()
|
||||
// will automatically read into the animation loop
|
||||
bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData, animationPropertiesChanged);
|
||||
});
|
||||
int bytesFromAnimation;
|
||||
withWriteLock([&] {
|
||||
// Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer()
|
||||
// will automatically read into the animation loop
|
||||
bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData, animationPropertiesChanged);
|
||||
});
|
||||
|
||||
bytesRead += bytesFromAnimation;
|
||||
dataAt += bytesFromAnimation;
|
||||
}
|
||||
bytesRead += bytesFromAnimation;
|
||||
dataAt += bytesFromAnimation;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
||||
|
||||
|
|
|
@ -464,76 +464,40 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
|
|||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor);
|
||||
// Because we're using AnimationLoop which will reset the frame index if you change it's running state
|
||||
// we want to read these values in the order they appear in the buffer, but call our setters in an
|
||||
// order that allows AnimationLoop to preserve the correct frame rate.
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) {
|
||||
SKIP_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float);
|
||||
SKIP_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float);
|
||||
SKIP_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool);
|
||||
SKIP_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, bool, setIsEmitting);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, bool, setIsEmitting);
|
||||
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
||||
READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles);
|
||||
READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan);
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate);
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) {
|
||||
// OLD PROP_EMIT_VELOCITY FAKEOUT
|
||||
SKIP_ENTITY_PROPERTY(PROP_EMIT_SPEED, glm::vec3);
|
||||
}
|
||||
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_MODIFICATIONS) {
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration);
|
||||
READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius);
|
||||
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) {
|
||||
// OLD PROP_VELOCITY_SPREAD FAKEOUT
|
||||
SKIP_ENTITY_PROPERTY(PROP_SPEED_SPREAD, glm::vec3);
|
||||
}
|
||||
} else {
|
||||
// OLD PROP_EMIT_ACCELERATION FAKEOUT
|
||||
SKIP_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float);
|
||||
// OLD PROP_ACCELERATION_SPREAD FAKEOUT
|
||||
SKIP_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float);
|
||||
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius);
|
||||
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration);
|
||||
READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius);
|
||||
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES) {
|
||||
READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart);
|
||||
READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart);
|
||||
READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish);
|
||||
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES) {
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, xColor, setColorSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR_START, xColor, setColorStart);
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, xColor, setColorFinish);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, xColor, setColorSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR_START, xColor, setColorStart);
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, xColor, setColorFinish);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish);
|
||||
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) {
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed);
|
||||
READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation);
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions);
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart);
|
||||
READ_ENTITY_PROPERTY(PROP_POLAR_START, float, setPolarStart);
|
||||
READ_ENTITY_PROPERTY(PROP_POLAR_FINISH, float, setPolarFinish);
|
||||
READ_ENTITY_PROPERTY(PROP_AZIMUTH_START, float, setAzimuthStart);
|
||||
READ_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, float, setAzimuthFinish);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed);
|
||||
READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread);
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation);
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions);
|
||||
READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart);
|
||||
READ_ENTITY_PROPERTY(PROP_POLAR_START, float, setPolarStart);
|
||||
READ_ENTITY_PROPERTY(PROP_POLAR_FINISH, float, setPolarFinish);
|
||||
READ_ENTITY_PROPERTY(PROP_AZIMUTH_START, float, setAzimuthStart);
|
||||
READ_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, float, setAzimuthFinish);
|
||||
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING) {
|
||||
READ_ENTITY_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, bool, setEmitterShouldTrail);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, bool, setEmitterShouldTrail);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
|
|
@ -92,6 +92,28 @@ void EntityScriptClient::callEntityServerMethod(QUuid entityID, const QString& m
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptServerServices::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) {
|
||||
// only valid to call this function if you are the entity script server
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
SharedNodePointer targetClient = nodeList->nodeWithUUID(clientSessionID);
|
||||
|
||||
if (nodeList->getOwnerType() == NodeType::EntityScriptServer && targetClient) {
|
||||
auto packetList = NLPacketList::create(PacketType::EntityScriptCallMethod, QByteArray(), true, true);
|
||||
|
||||
packetList->write(entityID.toRfc4122());
|
||||
|
||||
packetList->writeString(method);
|
||||
|
||||
quint16 paramCount = params.length();
|
||||
packetList->writePrimitive(paramCount);
|
||||
|
||||
foreach(const QString& param, params) {
|
||||
packetList->writeString(param);
|
||||
}
|
||||
|
||||
nodeList->sendPacketList(std::move(packetList), *targetClient);
|
||||
}
|
||||
}
|
||||
|
||||
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
|
|
@ -74,4 +74,11 @@ private:
|
|||
void forceFailureOfPendingRequests(SharedNodePointer node);
|
||||
};
|
||||
|
||||
|
||||
class EntityScriptServerServices : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
public:
|
||||
void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,9 +29,9 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityAdd:
|
||||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
return VERSION_ENTITIES_STROKE_COLOR_PROPERTY;
|
||||
case PacketType::EntityPhysics:
|
||||
return VERSION_ENTITIES_HAZE;
|
||||
return static_cast<PacketVersion>(EntityVersion::StrokeColorProperty);
|
||||
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::JSONFilterWithFamilyTree);
|
||||
case PacketType::AvatarIdentity:
|
||||
|
@ -62,6 +62,9 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::DomainServerAddedNode:
|
||||
return static_cast<PacketVersion>(DomainServerAddedNodeVersion::PermissionsGrid);
|
||||
|
||||
case PacketType::EntityScriptCallMethod:
|
||||
return static_cast<PacketVersion>(EntityScriptCallMethodVersion::ClientCallable);
|
||||
|
||||
case PacketType::MixedAudio:
|
||||
case PacketType::SilentAudioFrame:
|
||||
case PacketType::InjectAudio:
|
||||
|
|
|
@ -194,85 +194,14 @@ void sendWrongProtocolVersionsSignature(bool sendWrongVersion); /// for debuggin
|
|||
uint qHash(const PacketType& key, uint seed);
|
||||
QDebug operator<<(QDebug debug, const PacketType& type);
|
||||
|
||||
const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_ANIMATION = 1;
|
||||
const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2;
|
||||
const PacketVersion VERSION_ENTITIES_SUPPORT_SPLIT_MTU = 3;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_SPLIT_MTU;
|
||||
const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4;
|
||||
const PacketVersion VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS = 5;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_USER_DATA = 6;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME = 7;
|
||||
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SHAPE_TYPE = 8;
|
||||
const PacketVersion VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES = 9;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_PARTICLES = 10;
|
||||
const PacketVersion VERSION_ENTITIES_USE_METERS_AND_RADIANS = 11;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_COLLISION_MODEL = 12;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED = 13;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_MARKETPLACE_ID = 14;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_ACCELERATION = 15;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_UUIDS = 16;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_EXIST = 17;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE = 18;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_NAMES = 19;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE = 20;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX = 21;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_STAGE_HAS_AUTOMATIC_HOURDAY = 22;
|
||||
const PacketVersion VERSION_ENTITIES_PARTICLE_ENTITIES_HAVE_TEXTURES = 23;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_LINE_TYPE = 24;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_COLLISION_SOUND_URL = 25;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_FRICTION = 26;
|
||||
const PacketVersion VERSION_NO_ENTITY_ID_SWAP = 27;
|
||||
const PacketVersion VERSION_ENTITIES_PARTICLE_FIX = 28;
|
||||
const PacketVersion VERSION_ENTITIES_LINE_POINTS = 29;
|
||||
const PacketVersion VERSION_ENTITIES_FACE_CAMERA = 30;
|
||||
const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP = 31;
|
||||
const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP_FIX = 32;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE = 33;
|
||||
const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35;
|
||||
const PacketVersion VERSION_POLYVOX_TEXTURES = 36;
|
||||
const PacketVersion VERSION_ENTITIES_POLYLINE = 37;
|
||||
const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38;
|
||||
const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39;
|
||||
const PacketVersion VERSION_ENTITIES_POLYVOX_NEIGHBORS = 40;
|
||||
const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41;
|
||||
const PacketVersion VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES = 42;
|
||||
const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43;
|
||||
const PacketVersion VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER = 44;
|
||||
const PacketVersion VERSION_ENTITIES_PROTOCOL_CHANNELS = 45;
|
||||
const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 46;
|
||||
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP = 47;
|
||||
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48;
|
||||
const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49;
|
||||
const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51;
|
||||
const PacketVersion VERSION_ENTITIES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52;
|
||||
const PacketVersion VERSION_MODEL_ENTITIES_JOINTS_ON_WIRE = 53;
|
||||
const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 54;
|
||||
const PacketVersion VERSION_ENTITITES_HAVE_COLLISION_MASK = 55;
|
||||
const PacketVersion VERSION_ATMOSPHERE_REMOVED = 56;
|
||||
const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57;
|
||||
const PacketVersion VERSION_ENTITIES_NO_FLY_ZONES = 58;
|
||||
const PacketVersion VERSION_ENTITIES_MORE_SHAPES = 59;
|
||||
const PacketVersion VERSION_ENTITIES_PROPERLY_ENCODE_SHAPE_EDITS = 60;
|
||||
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_STATIC_MESH = 61;
|
||||
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SIMPLE_HULLS = 62;
|
||||
const PacketVersion VERSION_WEB_ENTITIES_SUPPORT_DPI = 63;
|
||||
const PacketVersion VERSION_ENTITIES_ARROW_ACTION = 64;
|
||||
const PacketVersion VERSION_ENTITIES_LAST_EDITED_BY = 65;
|
||||
const PacketVersion VERSION_ENTITIES_SERVER_SCRIPTS = 66;
|
||||
const PacketVersion VERSION_ENTITIES_PHYSICS_PACKET = 67;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_FILTERS = 68;
|
||||
const PacketVersion VERSION_ENTITIES_HINGE_CONSTRAINT = 69;
|
||||
const PacketVersion VERSION_ENTITIES_BULLET_DYNAMICS = 70;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT = 71;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE = 72;
|
||||
const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 73;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES = 74;
|
||||
const PacketVersion VERSION_ENTITIES_HAZE = 75;
|
||||
const PacketVersion VERSION_ENTITIES_UV_MODE_PROPERTY = 76;
|
||||
const PacketVersion VERSION_ENTITIES_STROKE_COLOR_PROPERTY = 77;
|
||||
enum class EntityVersion : PacketVersion {
|
||||
StrokeColorProperty = 77
|
||||
};
|
||||
|
||||
enum class EntityScriptCallMethodVersion : PacketVersion {
|
||||
ServerCallable = 18,
|
||||
ClientCallable = 19
|
||||
};
|
||||
|
||||
enum class EntityQueryPacketVersion: PacketVersion {
|
||||
JSONFilter = 18,
|
||||
|
|
|
@ -1721,8 +1721,8 @@ bool Octree::readFromStream(uint64_t streamLength, QDataStream& inputStream, con
|
|||
device->ungetChar(firstChar);
|
||||
|
||||
if (firstChar == (char) PacketType::EntityData) {
|
||||
qCDebug(octree) << "Reading from binary SVO Stream length:" << streamLength;
|
||||
return readSVOFromStream(streamLength, inputStream);
|
||||
qCWarning(octree) << "Reading from binary SVO no longer supported";
|
||||
return false;
|
||||
} else {
|
||||
qCDebug(octree) << "Reading from JSON SVO Stream length:" << streamLength;
|
||||
return readJSONFromStream(streamLength, inputStream, marketplaceID);
|
||||
|
@ -1730,137 +1730,6 @@ bool Octree::readFromStream(uint64_t streamLength, QDataStream& inputStream, con
|
|||
}
|
||||
|
||||
|
||||
bool Octree::readSVOFromStream(uint64_t streamLength, QDataStream& inputStream) {
|
||||
qWarning() << "SVO file format depricated. Support for reading SVO files is no longer support and will be removed soon.";
|
||||
|
||||
bool fileOk = false;
|
||||
|
||||
PacketVersion gotVersion = 0;
|
||||
|
||||
uint64_t headerLength = 0; // bytes in the header
|
||||
|
||||
bool wantImportProgress = true;
|
||||
|
||||
PacketType expectedType = expectedDataPacketType();
|
||||
PacketVersion expectedVersion = versionForPacketType(expectedType);
|
||||
bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion);
|
||||
|
||||
// before reading the file, check to see if this version of the Octree supports file versions
|
||||
if (getWantSVOfileVersions()) {
|
||||
|
||||
// read just enough of the file to parse the header...
|
||||
const uint64_t HEADER_LENGTH = sizeof(int) + sizeof(PacketVersion);
|
||||
unsigned char fileHeader[HEADER_LENGTH];
|
||||
inputStream.readRawData((char*)&fileHeader, HEADER_LENGTH);
|
||||
|
||||
headerLength = HEADER_LENGTH; // we need this later to skip to the data
|
||||
|
||||
unsigned char* dataAt = (unsigned char*)&fileHeader;
|
||||
uint64_t dataLength = HEADER_LENGTH;
|
||||
|
||||
// if so, read the first byte of the file and see if it matches the expected version code
|
||||
int intPacketType;
|
||||
memcpy(&intPacketType, dataAt, sizeof(intPacketType));
|
||||
PacketType gotType = (PacketType) intPacketType;
|
||||
|
||||
dataAt += sizeof(expectedType);
|
||||
dataLength -= sizeof(expectedType);
|
||||
gotVersion = *dataAt;
|
||||
|
||||
if (gotType == expectedType) {
|
||||
if (canProcessVersion(gotVersion)) {
|
||||
dataAt += sizeof(gotVersion);
|
||||
dataLength -= sizeof(gotVersion);
|
||||
fileOk = true;
|
||||
qCDebug(octree, "SVO file version match. Expected: %d Got: %d",
|
||||
versionForPacketType(expectedDataPacketType()), gotVersion);
|
||||
|
||||
hasBufferBreaks = versionHasSVOfileBreaks(gotVersion);
|
||||
} else {
|
||||
qCDebug(octree, "SVO file version mismatch. Expected: %d Got: %d",
|
||||
versionForPacketType(expectedDataPacketType()), gotVersion);
|
||||
}
|
||||
} else {
|
||||
qCDebug(octree) << "SVO file type mismatch. Expected: " << expectedType
|
||||
<< " Got: " << gotType;
|
||||
}
|
||||
|
||||
} else {
|
||||
qCDebug(octree) << " NOTE: this file type does not include type and version information.";
|
||||
fileOk = true; // assume the file is ok
|
||||
}
|
||||
|
||||
if (hasBufferBreaks) {
|
||||
qCDebug(octree) << " this version includes buffer breaks";
|
||||
} else {
|
||||
qCDebug(octree) << " this version does not include buffer breaks";
|
||||
}
|
||||
|
||||
if (fileOk) {
|
||||
|
||||
// if this version of the file does not include buffer breaks, then we need to load the entire file at once
|
||||
if (!hasBufferBreaks) {
|
||||
|
||||
// read the entire file into a buffer, WHAT!? Why not.
|
||||
uint64_t dataLength = streamLength - headerLength;
|
||||
unsigned char* entireFileDataSection = new unsigned char[dataLength];
|
||||
inputStream.readRawData((char*)entireFileDataSection, dataLength);
|
||||
|
||||
unsigned char* dataAt = entireFileDataSection;
|
||||
|
||||
ReadBitstreamToTreeParams args(NO_EXISTS_BITS, NULL, 0,
|
||||
SharedNodePointer(), wantImportProgress, gotVersion);
|
||||
|
||||
readBitstreamToTree(dataAt, dataLength, args);
|
||||
delete[] entireFileDataSection;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
uint64_t dataLength = streamLength - headerLength;
|
||||
uint64_t remainingLength = dataLength;
|
||||
const uint64_t MAX_CHUNK_LENGTH = MAX_OCTREE_PACKET_SIZE * 2;
|
||||
unsigned char* fileChunk = new unsigned char[MAX_CHUNK_LENGTH];
|
||||
|
||||
while (remainingLength > 0) {
|
||||
quint16 chunkLength = 0;
|
||||
|
||||
inputStream.readRawData((char*)&chunkLength, sizeof(chunkLength));
|
||||
remainingLength -= sizeof(chunkLength);
|
||||
|
||||
if (chunkLength > remainingLength) {
|
||||
qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength
|
||||
<< "greater than remaining length:" << remainingLength;
|
||||
break;
|
||||
}
|
||||
|
||||
if (chunkLength > MAX_CHUNK_LENGTH) {
|
||||
qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength
|
||||
<< "greater than MAX_CHUNK_LENGTH:" << MAX_CHUNK_LENGTH;
|
||||
break;
|
||||
}
|
||||
|
||||
inputStream.readRawData((char*)fileChunk, chunkLength);
|
||||
|
||||
remainingLength -= chunkLength;
|
||||
|
||||
unsigned char* dataAt = fileChunk;
|
||||
uint64_t dataLength = chunkLength;
|
||||
|
||||
ReadBitstreamToTreeParams args(NO_EXISTS_BITS, NULL, 0,
|
||||
SharedNodePointer(), wantImportProgress, gotVersion);
|
||||
|
||||
readBitstreamToTree(dataAt, dataLength, args);
|
||||
}
|
||||
|
||||
delete[] fileChunk;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return fileOk;
|
||||
}
|
||||
|
||||
// hack to get the marketplace id into the entities. We will create a way to get this from a hash of
|
||||
// the entity later, but this helps us move things along for now
|
||||
QJsonDocument addMarketplaceIDToDocumentEntities(QJsonDocument& doc, const QString& marketplaceID) {
|
||||
|
|
|
@ -208,8 +208,6 @@ public:
|
|||
// own definition. Implement these to allow your octree based server to support editing
|
||||
virtual bool getWantSVOfileVersions() const { return false; }
|
||||
virtual PacketType expectedDataPacketType() const { return PacketType::Unknown; }
|
||||
virtual bool canProcessVersion(PacketVersion thisVersion) const {
|
||||
return thisVersion == versionForPacketType(expectedDataPacketType()); }
|
||||
virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); }
|
||||
virtual bool handlesEditPacketType(PacketType packetType) const { return false; }
|
||||
virtual int processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength,
|
||||
|
@ -222,11 +220,6 @@ public:
|
|||
virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const { }
|
||||
virtual bool mustIncludeAllChildData() const { return true; }
|
||||
|
||||
/// some versions of the SVO file will include breaks with buffer lengths between each buffer chunk in the SVO
|
||||
/// file. If the Octree subclass expects this for this particular version of the file, it should override this
|
||||
/// method and return true.
|
||||
virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const { return false; }
|
||||
|
||||
virtual void update() { } // nothing to do by default
|
||||
|
||||
OctreeElementPointer getRoot() { return _rootElement; }
|
||||
|
|
|
@ -435,7 +435,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
|
|||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
assert(lightStage->getNumLights() > 0);
|
||||
auto lightAndShadow = lightStage->getLightAndShadow(0);
|
||||
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow();
|
||||
const auto& globalShadow = lightAndShadow.second;
|
||||
if (globalShadow) {
|
||||
batch.setResourceTexture(Shadow, globalShadow->map);
|
||||
|
|
|
@ -498,7 +498,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
assert(lightStage->getNumLights() > 0);
|
||||
auto lightAndShadow = lightStage->getLightAndShadow(0);
|
||||
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow();
|
||||
const auto& globalShadow = lightAndShadow.second;
|
||||
|
||||
// Bind the shadow buffer
|
||||
|
@ -509,7 +509,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
auto& program = deferredLightingEffect->_directionalSkyboxLight;
|
||||
LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations;
|
||||
|
||||
auto keyLight = lightStage->getLight(0);
|
||||
auto keyLight = lightAndShadow.first;
|
||||
|
||||
// Setup the global directional pass pipeline
|
||||
{
|
||||
|
|
|
@ -138,7 +138,8 @@ void main(void) {
|
|||
}
|
||||
|
||||
// Mix with background at far range
|
||||
if (distance > 32000.0) {
|
||||
const float BLEND_DISTANCE = 30000.0;
|
||||
if (distance > BLEND_DISTANCE) {
|
||||
outFragColor = mix(potentialFragColor, fragColor, hazeParams.backgroundBlendValue);
|
||||
} else {
|
||||
outFragColor = potentialFragColor;
|
||||
|
|
|
@ -142,6 +142,11 @@ LightStage::LightPointer LightStage::removeLight(Index index) {
|
|||
LightPointer removed = _lights.freeElement(index);
|
||||
|
||||
if (removed) {
|
||||
auto shadowId = _descs[index].shadowId;
|
||||
// Remove shadow if one exists for this light
|
||||
if (shadowId != INVALID_INDEX) {
|
||||
_shadows.freeElement(shadowId);
|
||||
}
|
||||
_lightMap.erase(removed);
|
||||
_descs[index] = Desc();
|
||||
}
|
||||
|
|
|
@ -116,6 +116,30 @@ public:
|
|||
return LightAndShadow(getLight(lightId), getShadow(lightId));
|
||||
}
|
||||
|
||||
LightPointer getCurrentKeyLight() const {
|
||||
Index keyLightId{ 0 };
|
||||
if (!_currentFrame._sunLights.empty()) {
|
||||
keyLightId = _currentFrame._sunLights.front();
|
||||
}
|
||||
return _lights.get(keyLightId);
|
||||
}
|
||||
|
||||
ShadowPointer getCurrentKeyShadow() const {
|
||||
Index keyLightId{ 0 };
|
||||
if (!_currentFrame._sunLights.empty()) {
|
||||
keyLightId = _currentFrame._sunLights.front();
|
||||
}
|
||||
return getShadow(keyLightId);
|
||||
}
|
||||
|
||||
LightAndShadow getCurrentKeyLightAndShadow() const {
|
||||
Index keyLightId{ 0 };
|
||||
if (!_currentFrame._sunLights.empty()) {
|
||||
keyLightId = _currentFrame._sunLights.front();
|
||||
}
|
||||
return LightAndShadow(getLight(keyLightId), getShadow(keyLightId));
|
||||
}
|
||||
|
||||
LightStage();
|
||||
Lights _lights;
|
||||
LightMap _lightMap;
|
||||
|
|
|
@ -33,10 +33,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
LightStage::Index globalLightIndex { 0 };
|
||||
|
||||
const auto globalLight = lightStage->getLight(globalLightIndex);
|
||||
const auto shadow = lightStage->getShadow(globalLightIndex);
|
||||
const auto shadow = lightStage->getCurrentKeyShadow();
|
||||
if (!shadow) return;
|
||||
|
||||
const auto& fbo = shadow->framebuffer;
|
||||
|
@ -128,20 +126,22 @@ void RenderShadowTask::configure(const Config& configuration) {
|
|||
void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Output& output) {
|
||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||
assert(lightStage);
|
||||
const auto globalShadow = lightStage->getShadow(0);
|
||||
|
||||
// Cache old render args
|
||||
RenderArgs* args = renderContext->args;
|
||||
output = args->_renderMode;
|
||||
const auto globalShadow = lightStage->getCurrentKeyShadow();
|
||||
if (globalShadow) {
|
||||
// Cache old render args
|
||||
RenderArgs* args = renderContext->args;
|
||||
output = args->_renderMode;
|
||||
|
||||
auto nearClip = args->getViewFrustum().getNearClip();
|
||||
float nearDepth = -args->_boomOffset.z;
|
||||
const int SHADOW_FAR_DEPTH = 20;
|
||||
globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH);
|
||||
auto nearClip = args->getViewFrustum().getNearClip();
|
||||
float nearDepth = -args->_boomOffset.z;
|
||||
const int SHADOW_FAR_DEPTH = 20;
|
||||
globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH);
|
||||
|
||||
// Set the keylight render args
|
||||
args->pushViewFrustum(*(globalShadow->getFrustum()));
|
||||
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;
|
||||
// Set the keylight render args
|
||||
args->pushViewFrustum(*(globalShadow->getFrustum()));
|
||||
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderShadowTeardown::run(const render::RenderContextPointer& renderContext, const Input& input) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// examples
|
||||
//
|
||||
// Created by Brad hefta-Gaub on 10/1/14.
|
||||
// Modified by Daniela Fontes @DanielaFifo and Tiago Andrade @TagoWill on 4/7/2017
|
||||
// Modified by Daniela Fontes * @DanielaFifo and Tiago Andrade @TagoWill on 4/7/2017
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This script implements a class useful for building tools for editing entities.
|
||||
|
@ -203,6 +203,7 @@ SelectionManager = (function() {
|
|||
print("ERROR: entitySelectionTool.update got exception: " + JSON.stringify(e));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return that;
|
||||
|
@ -1422,11 +1423,11 @@ SelectionDisplay = (function() {
|
|||
Overlays.editOverlay(rollHandle, {
|
||||
scale: handleSize
|
||||
});
|
||||
var pos = Vec3.sum(grabberMoveUpPosition, {
|
||||
x: 0,
|
||||
y: Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 3,
|
||||
z: 0
|
||||
});
|
||||
var upDiff = Vec3.multiply((
|
||||
Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 3),
|
||||
Quat.getUp(MyAvatar.orientation)
|
||||
);
|
||||
var pos = Vec3.sum(grabberMoveUpPosition, upDiff);
|
||||
Overlays.editOverlay(grabberMoveUp, {
|
||||
position: pos,
|
||||
scale: handleSize / 1.25
|
||||
|
@ -2099,10 +2100,11 @@ SelectionDisplay = (function() {
|
|||
});
|
||||
|
||||
var grabberMoveUpOffset = 0.1;
|
||||
var upVec = Quat.getUp(MyAvatar.orientation);
|
||||
grabberMoveUpPosition = {
|
||||
x: position.x,
|
||||
y: position.y + worldTop + grabberMoveUpOffset,
|
||||
z: position.z
|
||||
x: position.x + (grabberMoveUpOffset + worldTop) * upVec.x ,
|
||||
y: position.y+ (grabberMoveUpOffset + worldTop) * upVec.y,
|
||||
z: position.z + (grabberMoveUpOffset + worldTop) * upVec.z
|
||||
};
|
||||
Overlays.editOverlay(grabberMoveUp, {
|
||||
visible: (!activeTool) || isActiveTool(grabberMoveUp)
|
||||
|
@ -2416,9 +2418,6 @@ SelectionDisplay = (function() {
|
|||
mode: "TRANSLATE_UP_DOWN",
|
||||
onBegin: function(event, pickRay, pickResult) {
|
||||
upDownPickNormal = Quat.getForward(lastCameraOrientation);
|
||||
// Remove y component so the y-axis lies along the plane we're picking on - this will
|
||||
// give movements that follow the mouse.
|
||||
upDownPickNormal.y = 0;
|
||||
lastXYPick = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, upDownPickNormal);
|
||||
|
||||
SelectionManager.saveProperties();
|
||||
|
@ -2455,11 +2454,17 @@ SelectionDisplay = (function() {
|
|||
var newIntersection = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, upDownPickNormal);
|
||||
|
||||
var vector = Vec3.subtract(newIntersection, lastXYPick);
|
||||
|
||||
// project vector onto avatar up vector
|
||||
// we want the avatar referential not the camera.
|
||||
var avatarUpVector = Quat.getUp(MyAvatar.orientation);
|
||||
var dotVectorUp = Vec3.dot(vector, avatarUpVector);
|
||||
vector = Vec3.multiply(dotVectorUp, avatarUpVector);
|
||||
|
||||
|
||||
vector = grid.snapToGrid(vector);
|
||||
|
||||
// we only care about the Y axis
|
||||
vector.x = 0;
|
||||
vector.z = 0;
|
||||
|
||||
|
||||
var wantDebug = false;
|
||||
if (wantDebug) {
|
||||
|
|
Loading…
Reference in a new issue