mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge branch 'master' of https://github.com/highfidelity/hifi into log-filter2
This commit is contained in:
commit
efdba3b6e6
64 changed files with 615 additions and 310 deletions
|
@ -214,7 +214,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
||||||
uint64_t getTimestamp() const override {
|
uint64_t getTimestamp() const override {
|
||||||
return _lastEncodeTime;
|
return _lastEncodeTime;
|
||||||
}
|
}
|
||||||
const AvatarSharedPointer& getAvatar() const { return _avatar; }
|
AvatarSharedPointer getAvatar() const { return _avatar; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AvatarSharedPointer _avatar;
|
AvatarSharedPointer _avatar;
|
||||||
|
@ -326,7 +326,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
||||||
|
|
||||||
int remainingAvatars = (int)sortedAvatars.size();
|
int remainingAvatars = (int)sortedAvatars.size();
|
||||||
while (!sortedAvatars.empty()) {
|
while (!sortedAvatars.empty()) {
|
||||||
const auto& avatarData = sortedAvatars.top().getAvatar();
|
const auto avatarData = sortedAvatars.top().getAvatar();
|
||||||
sortedAvatars.pop();
|
sortedAvatars.pop();
|
||||||
remainingAvatars--;
|
remainingAvatars--;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ Rectangle {
|
||||||
property string itemName;
|
property string itemName;
|
||||||
property string itemId;
|
property string itemId;
|
||||||
property string itemHref;
|
property string itemHref;
|
||||||
|
property string itemAuthor;
|
||||||
property double balanceAfterPurchase;
|
property double balanceAfterPurchase;
|
||||||
property bool alreadyOwned: false;
|
property bool alreadyOwned: false;
|
||||||
property int itemPrice: -1;
|
property int itemPrice: -1;
|
||||||
|
@ -81,12 +82,12 @@ Rectangle {
|
||||||
if (result.status !== 'success') {
|
if (result.status !== 'success') {
|
||||||
failureErrorText.text = result.message;
|
failureErrorText.text = result.message;
|
||||||
root.activeView = "checkoutFailure";
|
root.activeView = "checkoutFailure";
|
||||||
UserActivityLogger.commercePurchaseFailure(root.itemId, root.itemPrice, !root.alreadyOwned, result.message);
|
UserActivityLogger.commercePurchaseFailure(root.itemId, root.itemAuthor, root.itemPrice, !root.alreadyOwned, result.message);
|
||||||
} else {
|
} else {
|
||||||
root.itemHref = result.data.download_url;
|
root.itemHref = result.data.download_url;
|
||||||
root.isWearable = result.data.categories.indexOf("Wearables") > -1;
|
root.isWearable = result.data.categories.indexOf("Wearables") > -1;
|
||||||
root.activeView = "checkoutSuccess";
|
root.activeView = "checkoutSuccess";
|
||||||
UserActivityLogger.commercePurchaseSuccess(root.itemId, root.itemPrice, !root.alreadyOwned);
|
UserActivityLogger.commercePurchaseSuccess(root.itemId, root.itemAuthor, root.itemPrice, !root.alreadyOwned);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,6 +881,7 @@ Rectangle {
|
||||||
root.itemPrice = message.params.itemPrice;
|
root.itemPrice = message.params.itemPrice;
|
||||||
itemHref = message.params.itemHref;
|
itemHref = message.params.itemHref;
|
||||||
referrer = message.params.referrer;
|
referrer = message.params.referrer;
|
||||||
|
itemAuthor = message.params.itemAuthor;
|
||||||
setBuyText();
|
setBuyText();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -4279,7 +4279,7 @@ void Application::init() {
|
||||||
|
|
||||||
getEntities()->init();
|
getEntities()->init();
|
||||||
getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) {
|
getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) {
|
||||||
auto dims = item.getDimensions();
|
auto dims = item.getScaledDimensions();
|
||||||
auto maxSize = glm::compMax(dims);
|
auto maxSize = glm::compMax(dims);
|
||||||
|
|
||||||
if (maxSize <= 0.0f) {
|
if (maxSize <= 0.0f) {
|
||||||
|
@ -4633,7 +4633,7 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
|
||||||
_lastAcceptedKeyPress = usecTimestampNow();
|
_lastAcceptedKeyPress = usecTimestampNow();
|
||||||
|
|
||||||
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
|
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
|
||||||
entity->getDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
|
entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,7 +407,7 @@ void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &s
|
||||||
ShapeInfo::PointList points;
|
ShapeInfo::PointList points;
|
||||||
pointCollection.push_back(points);
|
pointCollection.push_back(points);
|
||||||
|
|
||||||
GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getDimensions(), pointCollection.back());
|
GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getScaledDimensions(), pointCollection.back());
|
||||||
shapeInfo.setPointCollection(pointCollection);
|
shapeInfo.setPointCollection(pointCollection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
glm::vec3 getPosition() const override { return _avatar->getWorldPosition(); }
|
glm::vec3 getPosition() const override { return _avatar->getWorldPosition(); }
|
||||||
float getRadius() const override { return std::static_pointer_cast<Avatar>(_avatar)->getBoundingRadius(); }
|
float getRadius() const override { return std::static_pointer_cast<Avatar>(_avatar)->getBoundingRadius(); }
|
||||||
uint64_t getTimestamp() const override { return std::static_pointer_cast<Avatar>(_avatar)->getLastRenderUpdateTime(); }
|
uint64_t getTimestamp() const override { return std::static_pointer_cast<Avatar>(_avatar)->getLastRenderUpdateTime(); }
|
||||||
const AvatarSharedPointer& getAvatar() const { return _avatar; }
|
AvatarSharedPointer getAvatar() const { return _avatar; }
|
||||||
private:
|
private:
|
||||||
AvatarSharedPointer _avatar;
|
AvatarSharedPointer _avatar;
|
||||||
};
|
};
|
||||||
|
@ -185,7 +185,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
while (!sortedAvatars.empty()) {
|
while (!sortedAvatars.empty()) {
|
||||||
const SortableAvatar& sortData = sortedAvatars.top();
|
const SortableAvatar& sortData = sortedAvatars.top();
|
||||||
const auto& avatar = std::static_pointer_cast<Avatar>(sortData.getAvatar());
|
const auto avatar = std::static_pointer_cast<Avatar>(sortData.getAvatar());
|
||||||
|
|
||||||
bool ignoring = DependencyManager::get<NodeList>()->isPersonalMutingNode(avatar->getID());
|
bool ignoring = DependencyManager::get<NodeList>()->isPersonalMutingNode(avatar->getID());
|
||||||
if (ignoring) {
|
if (ignoring) {
|
||||||
|
@ -239,7 +239,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
sortedAvatars.pop();
|
sortedAvatars.pop();
|
||||||
while (inView && !sortedAvatars.empty()) {
|
while (inView && !sortedAvatars.empty()) {
|
||||||
const SortableAvatar& newSortData = sortedAvatars.top();
|
const SortableAvatar& newSortData = sortedAvatars.top();
|
||||||
const auto& newAvatar = std::static_pointer_cast<Avatar>(newSortData.getAvatar());
|
const auto newAvatar = std::static_pointer_cast<Avatar>(newSortData.getAvatar());
|
||||||
inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
|
inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD;
|
||||||
if (inView && newAvatar->hasNewJointData()) {
|
if (inView && newAvatar->hasNewJointData()) {
|
||||||
numAVatarsNotUpdated++;
|
numAVatarsNotUpdated++;
|
||||||
|
|
|
@ -42,7 +42,7 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
|
||||||
setTransform(base3DOverlay->getTransform());
|
setTransform(base3DOverlay->getTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties) {
|
QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties, bool scalesWithParent) {
|
||||||
// the position and rotation in _transform are relative to the parent (aka local). The versions coming from
|
// the position and rotation in _transform are relative to the parent (aka local). The versions coming from
|
||||||
// scripts are in world-frame, unless localPosition or localRotation are used. Patch up the properties
|
// scripts are in world-frame, unless localPosition or localRotation are used. Patch up the properties
|
||||||
// so that "position" and "rotation" are relative-to-parent values.
|
// so that "position" and "rotation" are relative-to-parent values.
|
||||||
|
@ -56,7 +56,7 @@ QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& propert
|
||||||
result["position"] = result["localPosition"];
|
result["position"] = result["localPosition"];
|
||||||
} else if (result["position"].isValid()) {
|
} else if (result["position"].isValid()) {
|
||||||
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(vec3FromVariant(result["position"]),
|
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(vec3FromVariant(result["position"]),
|
||||||
parentID, parentJointIndex, success);
|
parentID, parentJointIndex, scalesWithParent, success);
|
||||||
if (success) {
|
if (success) {
|
||||||
result["position"] = vec3toVariant(localPosition);
|
result["position"] = vec3toVariant(localPosition);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& propert
|
||||||
result["orientation"] = result["localOrientation"];
|
result["orientation"] = result["localOrientation"];
|
||||||
} else if (result["orientation"].isValid()) {
|
} else if (result["orientation"].isValid()) {
|
||||||
glm::quat localOrientation = SpatiallyNestable::worldToLocal(quatFromVariant(result["orientation"]),
|
glm::quat localOrientation = SpatiallyNestable::worldToLocal(quatFromVariant(result["orientation"]),
|
||||||
parentID, parentJointIndex, success);
|
parentID, parentJointIndex, scalesWithParent, success);
|
||||||
if (success) {
|
if (success) {
|
||||||
result["orientation"] = quatToVariant(localOrientation);
|
result["orientation"] = quatToVariant(localOrientation);
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
properties = convertOverlayLocationFromScriptSemantics(properties);
|
properties = convertOverlayLocationFromScriptSemantics(properties, getScalesWithParent());
|
||||||
Overlay::setProperties(properties);
|
Overlay::setProperties(properties);
|
||||||
|
|
||||||
bool needRenderItemUpdate = false;
|
bool needRenderItemUpdate = false;
|
||||||
|
|
|
@ -56,12 +56,12 @@ glm::vec3 Line3DOverlay::getEnd() const {
|
||||||
if (_endParentID != QUuid()) {
|
if (_endParentID != QUuid()) {
|
||||||
glm::vec3 localOffset = _direction * _length;
|
glm::vec3 localOffset = _direction * _length;
|
||||||
bool success;
|
bool success;
|
||||||
worldEnd = localToWorld(localOffset, _endParentID, _endParentJointIndex, success);
|
worldEnd = localToWorld(localOffset, _endParentID, _endParentJointIndex, getScalesWithParent(), success);
|
||||||
return worldEnd;
|
return worldEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
localEnd = getLocalEnd();
|
localEnd = getLocalEnd();
|
||||||
worldEnd = localToWorld(localEnd, getParentID(), getParentJointIndex(), success);
|
worldEnd = localToWorld(localEnd, getParentID(), getParentJointIndex(), getScalesWithParent(), success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
qDebug() << "Line3DOverlay::getEnd failed";
|
qDebug() << "Line3DOverlay::getEnd failed";
|
||||||
}
|
}
|
||||||
|
@ -79,10 +79,10 @@ void Line3DOverlay::setEnd(const glm::vec3& end) {
|
||||||
glm::vec3 offset;
|
glm::vec3 offset;
|
||||||
|
|
||||||
if (_endParentID != QUuid()) {
|
if (_endParentID != QUuid()) {
|
||||||
offset = worldToLocal(end, _endParentID, _endParentJointIndex, success);
|
offset = worldToLocal(end, _endParentID, _endParentJointIndex, getScalesWithParent(), success);
|
||||||
} else {
|
} else {
|
||||||
localStart = getLocalStart();
|
localStart = getLocalStart();
|
||||||
localEnd = worldToLocal(end, getParentID(), getParentJointIndex(), success);
|
localEnd = worldToLocal(end, getParentID(), getParentJointIndex(), getScalesWithParent(), success);
|
||||||
offset = localEnd - localStart;
|
offset = localEnd - localStart;
|
||||||
}
|
}
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
|
|
@ -24,7 +24,6 @@ ModelOverlay::ModelOverlay()
|
||||||
: _model(std::make_shared<Model>(nullptr, this)),
|
: _model(std::make_shared<Model>(nullptr, this)),
|
||||||
_modelTextures(QVariantMap())
|
_modelTextures(QVariantMap())
|
||||||
{
|
{
|
||||||
_model->init();
|
|
||||||
_model->setLoadingPriority(_loadPriority);
|
_model->setLoadingPriority(_loadPriority);
|
||||||
_isLoaded = false;
|
_isLoaded = false;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +37,6 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) :
|
||||||
_scaleToFit(modelOverlay->_scaleToFit),
|
_scaleToFit(modelOverlay->_scaleToFit),
|
||||||
_loadPriority(modelOverlay->_loadPriority)
|
_loadPriority(modelOverlay->_loadPriority)
|
||||||
{
|
{
|
||||||
_model->init();
|
|
||||||
_model->setLoadingPriority(_loadPriority);
|
_model->setLoadingPriority(_loadPriority);
|
||||||
if (_url.isValid()) {
|
if (_url.isValid()) {
|
||||||
_updateModel = true;
|
_updateModel = true;
|
||||||
|
|
|
@ -138,7 +138,6 @@ Avatar::~Avatar() {
|
||||||
|
|
||||||
void Avatar::init() {
|
void Avatar::init() {
|
||||||
getHead()->init();
|
getHead()->init();
|
||||||
_skeletonModel->init();
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,6 +268,7 @@ public:
|
||||||
|
|
||||||
virtual float getModelScale() const { return _modelScale; }
|
virtual float getModelScale() const { return _modelScale; }
|
||||||
virtual void setModelScale(float scale) { _modelScale = scale; }
|
virtual void setModelScale(float scale) { _modelScale = scale; }
|
||||||
|
virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getModelScale()); }
|
||||||
|
|
||||||
virtual void setAvatarEntityDataChanged(bool value) override;
|
virtual void setAvatarEntityDataChanged(bool value) override;
|
||||||
|
|
||||||
|
|
|
@ -349,7 +349,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
|
||||||
float getRadius() const override { return 0.5f * _renderer->getEntity()->getQueryAACube().getScale(); }
|
float getRadius() const override { return 0.5f * _renderer->getEntity()->getQueryAACube().getScale(); }
|
||||||
uint64_t getTimestamp() const override { return _renderer->getUpdateTime(); }
|
uint64_t getTimestamp() const override { return _renderer->getUpdateTime(); }
|
||||||
|
|
||||||
const EntityRendererPointer& getRenderer() const { return _renderer; }
|
EntityRendererPointer getRenderer() const { return _renderer; }
|
||||||
private:
|
private:
|
||||||
EntityRendererPointer _renderer;
|
EntityRendererPointer _renderer;
|
||||||
};
|
};
|
||||||
|
@ -382,7 +382,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
|
||||||
std::unordered_map<EntityItemID, EntityRendererPointer>::iterator itr;
|
std::unordered_map<EntityItemID, EntityRendererPointer>::iterator itr;
|
||||||
size_t numSorted = sortedRenderables.size();
|
size_t numSorted = sortedRenderables.size();
|
||||||
while (!sortedRenderables.empty() && usecTimestampNow() < expiry) {
|
while (!sortedRenderables.empty() && usecTimestampNow() < expiry) {
|
||||||
const EntityRendererPointer& renderable = sortedRenderables.top().getRenderer();
|
const auto renderable = sortedRenderables.top().getRenderer();
|
||||||
renderable->updateInScene(scene, transaction);
|
renderable->updateInScene(scene, transaction);
|
||||||
_renderablesToUpdate.erase(renderable->getEntity()->getID());
|
_renderablesToUpdate.erase(renderable->getEntity()->getID());
|
||||||
sortedRenderables.pop();
|
sortedRenderables.pop();
|
||||||
|
@ -612,7 +612,7 @@ static glm::vec2 projectOntoEntityXYPlane(EntityItemPointer entity, const PickRa
|
||||||
|
|
||||||
glm::vec3 entityPosition = entity->getWorldPosition();
|
glm::vec3 entityPosition = entity->getWorldPosition();
|
||||||
glm::quat entityRotation = entity->getWorldOrientation();
|
glm::quat entityRotation = entity->getWorldOrientation();
|
||||||
glm::vec3 entityDimensions = entity->getDimensions();
|
glm::vec3 entityDimensions = entity->getScaledDimensions();
|
||||||
glm::vec3 entityRegistrationPoint = entity->getRegistrationPoint();
|
glm::vec3 entityRegistrationPoint = entity->getRegistrationPoint();
|
||||||
|
|
||||||
// project the intersection point onto the local xy plane of the object.
|
// project the intersection point onto the local xy plane of the object.
|
||||||
|
|
|
@ -37,7 +37,7 @@ void LightEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
||||||
lightPayload.editBound() = render::Item::Bound();
|
lightPayload.editBound() = render::Item::Bound();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 dimensions = entity->getDimensions();
|
glm::vec3 dimensions = entity->getScaledDimensions();
|
||||||
float largestDiameter = glm::compMax(dimensions);
|
float largestDiameter = glm::compMax(dimensions);
|
||||||
light->setMaximumRadius(largestDiameter / 2.0f);
|
light->setMaximumRadius(largestDiameter / 2.0f);
|
||||||
|
|
||||||
|
|
|
@ -78,11 +78,11 @@ RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityI
|
||||||
|
|
||||||
RenderableModelEntityItem::~RenderableModelEntityItem() { }
|
RenderableModelEntityItem::~RenderableModelEntityItem() { }
|
||||||
|
|
||||||
void RenderableModelEntityItem::setDimensions(const glm::vec3& value) {
|
void RenderableModelEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions
|
glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions
|
||||||
if (getDimensions() != newDimensions) {
|
if (getUnscaledDimensions() != newDimensions) {
|
||||||
_dimensionsInitialized = true;
|
_dimensionsInitialized = true;
|
||||||
ModelEntityItem::setDimensions(value);
|
ModelEntityItem::setUnscaledDimensions(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,11 +124,11 @@ void RenderableModelEntityItem::doInitialModelSimulation() {
|
||||||
// translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to
|
// translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to
|
||||||
// make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the
|
// make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the
|
||||||
// entity values to change -- it just allows the model to match once it comes in.
|
// entity values to change -- it just allows the model to match once it comes in.
|
||||||
model->setScaleToFit(false, getDimensions());
|
model->setScaleToFit(false, getScaledDimensions());
|
||||||
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
|
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
|
||||||
|
|
||||||
// now recalculate the bounds and registration
|
// now recalculate the bounds and registration
|
||||||
model->setScaleToFit(true, getDimensions());
|
model->setScaleToFit(true, getScaledDimensions());
|
||||||
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
||||||
model->setRotation(getWorldOrientation());
|
model->setRotation(getWorldOrientation());
|
||||||
model->setTranslation(getWorldPosition());
|
model->setTranslation(getWorldPosition());
|
||||||
|
@ -169,7 +169,7 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->getScaleToFitDimensions() != getDimensions()) {
|
if (model->getScaleToFitDimensions() != getScaledDimensions()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,17 +209,17 @@ void RenderableModelEntityItem::updateModelBounds() {
|
||||||
updateRenderItems = true;
|
updateRenderItems = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->getScaleToFitDimensions() != getDimensions() ||
|
if (model->getScaleToFitDimensions() != getScaledDimensions() ||
|
||||||
model->getRegistrationPoint() != getRegistrationPoint()) {
|
model->getRegistrationPoint() != getRegistrationPoint()) {
|
||||||
// The machinery for updateModelBounds will give existing models the opportunity to fix their
|
// The machinery for updateModelBounds will give existing models the opportunity to fix their
|
||||||
// translation/rotation/scale/registration. The first two are straightforward, but the latter two
|
// translation/rotation/scale/registration. The first two are straightforward, but the latter two
|
||||||
// have guards to make sure they don't happen after they've already been set. Here we reset those guards.
|
// have guards to make sure they don't happen after they've already been set. Here we reset those guards.
|
||||||
// This doesn't cause the entity values to change -- it just allows the model to match once it comes in.
|
// This doesn't cause the entity values to change -- it just allows the model to match once it comes in.
|
||||||
model->setScaleToFit(false, getDimensions());
|
model->setScaleToFit(false, getScaledDimensions());
|
||||||
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
|
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
|
||||||
|
|
||||||
// now recalculate the bounds and registration
|
// now recalculate the bounds and registration
|
||||||
model->setScaleToFit(true, getDimensions());
|
model->setScaleToFit(true, getScaledDimensions());
|
||||||
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
||||||
updateRenderItems = true;
|
updateRenderItems = true;
|
||||||
model->scaleToFit();
|
model->scaleToFit();
|
||||||
|
@ -372,7 +372,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
const uint32_t QUAD_STRIDE = 4;
|
const uint32_t QUAD_STRIDE = 4;
|
||||||
|
|
||||||
ShapeType type = getShapeType();
|
ShapeType type = getShapeType();
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
auto model = getModel();
|
auto model = getModel();
|
||||||
if (type == SHAPE_TYPE_COMPOUND) {
|
if (type == SHAPE_TYPE_COMPOUND) {
|
||||||
updateModelBounds();
|
updateModelBounds();
|
||||||
|
@ -1153,7 +1153,7 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->getScaleToFitDimensions() != entity->getDimensions() ||
|
if (model->getScaleToFitDimensions() != entity->getScaledDimensions() ||
|
||||||
model->getRegistrationPoint() != entity->getRegistrationPoint()) {
|
model->getRegistrationPoint() != entity->getRegistrationPoint()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1209,7 +1209,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
|
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
|
||||||
connect(entity.get(), &RenderableModelEntityItem::requestCollisionGeometryUpdate, this, &ModelEntityRenderer::flagForCollisionGeometryUpdate);
|
connect(entity.get(), &RenderableModelEntityItem::requestCollisionGeometryUpdate, this, &ModelEntityRenderer::flagForCollisionGeometryUpdate);
|
||||||
model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity));
|
model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity));
|
||||||
model->init();
|
|
||||||
entity->setModel(model);
|
entity->setModel(model);
|
||||||
withWriteLock([&] { _model = model; });
|
withWriteLock([&] { _model = model; });
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized);
|
RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized);
|
||||||
virtual ~RenderableModelEntityItem();
|
virtual ~RenderableModelEntityItem();
|
||||||
|
|
||||||
virtual void setDimensions(const glm::vec3& value) override;
|
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
|
|
||||||
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
|
||||||
void doInitialModelSimulation();
|
void doInitialModelSimulation();
|
||||||
|
|
|
@ -303,6 +303,7 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
||||||
batch.setInputBuffer(0, _verticesBuffer, 0, sizeof(Vertex));
|
batch.setInputBuffer(0, _verticesBuffer, 0, sizeof(Vertex));
|
||||||
|
|
||||||
#ifndef POLYLINE_ENTITY_USE_FADE_EFFECT
|
#ifndef POLYLINE_ENTITY_USE_FADE_EFFECT
|
||||||
|
// glColor4f must be called after setInputFormat if it must be taken into account
|
||||||
if (_isFading) {
|
if (_isFading) {
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, Interpolate::calculateFadeRatio(_fadeStartTime));
|
batch._glColor4f(1.0f, 1.0f, 1.0f, Interpolate::calculateFadeRatio(_fadeStartTime));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -213,7 +213,7 @@ void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxel
|
||||||
glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const {
|
glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const {
|
||||||
glm::vec3 result;
|
glm::vec3 result;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units
|
glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units
|
||||||
if (isEdged(_voxelSurfaceStyle)) {
|
if (isEdged(_voxelSurfaceStyle)) {
|
||||||
result = scale / -2.0f;
|
result = scale / -2.0f;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const {
|
||||||
voxelVolumeSize = _voxelVolumeSize;
|
voxelVolumeSize = _voxelVolumeSize;
|
||||||
});
|
});
|
||||||
|
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
|
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
|
||||||
bool success; // TODO -- Does this actually have to happen in world space?
|
bool success; // TODO -- Does this actually have to happen in world space?
|
||||||
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes
|
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes
|
||||||
|
@ -393,7 +393,7 @@ bool RenderablePolyVoxEntityItem::setSphere(const vec3& centerWorldCoords, float
|
||||||
glm::mat4 vtwMatrix = voxelToWorldMatrix();
|
glm::mat4 vtwMatrix = voxelToWorldMatrix();
|
||||||
glm::mat4 wtvMatrix = glm::inverse(vtwMatrix);
|
glm::mat4 wtvMatrix = glm::inverse(vtwMatrix);
|
||||||
|
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 voxelSize = dimensions / _voxelVolumeSize;
|
glm::vec3 voxelSize = dimensions / _voxelVolumeSize;
|
||||||
float smallestDimensionSize = voxelSize.x;
|
float smallestDimensionSize = voxelSize.x;
|
||||||
smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y);
|
smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y);
|
||||||
|
@ -454,7 +454,7 @@ bool RenderablePolyVoxEntityItem::setCapsule(const vec3& startWorldCoords, const
|
||||||
glm::mat4 vtwMatrix = voxelToWorldMatrix();
|
glm::mat4 vtwMatrix = voxelToWorldMatrix();
|
||||||
glm::mat4 wtvMatrix = glm::inverse(vtwMatrix);
|
glm::mat4 wtvMatrix = glm::inverse(vtwMatrix);
|
||||||
|
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 voxelSize = dimensions / _voxelVolumeSize;
|
glm::vec3 voxelSize = dimensions / _voxelVolumeSize;
|
||||||
float smallestDimensionSize = voxelSize.x;
|
float smallestDimensionSize = voxelSize.x;
|
||||||
smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y);
|
smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y);
|
||||||
|
@ -580,7 +580,7 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
||||||
// the PolyVox ray intersection code requires a near and far point.
|
// the PolyVox ray intersection code requires a near and far point.
|
||||||
// set ray cast length to long enough to cover all of the voxel space
|
// set ray cast length to long enough to cover all of the voxel space
|
||||||
float distanceToEntity = glm::distance(origin, getWorldPosition());
|
float distanceToEntity = glm::distance(origin, getWorldPosition());
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
float largestDimension = glm::compMax(dimensions) * 2.0f;
|
float largestDimension = glm::compMax(dimensions) * 2.0f;
|
||||||
glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension);
|
glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension);
|
||||||
|
|
||||||
|
@ -668,7 +668,7 @@ bool RenderablePolyVoxEntityItem::isReadyToComputeShape() const {
|
||||||
void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
|
void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
ShapeType shapeType = getShapeType();
|
ShapeType shapeType = getShapeType();
|
||||||
if (shapeType == SHAPE_TYPE_NONE) {
|
if (shapeType == SHAPE_TYPE_NONE) {
|
||||||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
info.setParams(getShapeType(), 0.5f * getScaledDimensions());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dimensions != entity->getDimensions()) {
|
if (_dimensions != entity->getScaledDimensions()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
|
|
||||||
_shape = entity->getShape();
|
_shape = entity->getShape();
|
||||||
_position = entity->getWorldPosition();
|
_position = entity->getWorldPosition();
|
||||||
_dimensions = entity->getDimensions();
|
_dimensions = entity->getScaledDimensions();
|
||||||
_orientation = entity->getWorldOrientation();
|
_orientation = entity->getWorldOrientation();
|
||||||
_renderTransform = getModelTransform();
|
_renderTransform = getModelTransform();
|
||||||
|
|
||||||
|
@ -137,11 +137,10 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (proceduralRender) {
|
if (proceduralRender) {
|
||||||
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
|
||||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||||
geometryCache->renderWireShape(batch, geometryShape);
|
geometryCache->renderWireShape(batch, geometryShape, outColor);
|
||||||
} else {
|
} else {
|
||||||
geometryCache->renderShape(batch, geometryShape);
|
geometryCache->renderShape(batch, geometryShape, outColor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||||
|
|
|
@ -54,7 +54,7 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dimensions != entity->getDimensions()) {
|
if (_dimensions != entity->getScaledDimensions()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
|
||||||
void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||||
_textColor = toGlm(entity->getTextColorX());
|
_textColor = toGlm(entity->getTextColorX());
|
||||||
_backgroundColor = toGlm(entity->getBackgroundColorX());
|
_backgroundColor = toGlm(entity->getBackgroundColorX());
|
||||||
_dimensions = entity->getDimensions();
|
_dimensions = entity->getScaledDimensions();
|
||||||
_faceCamera = entity->getFaceCamera();
|
_faceCamera = entity->getFaceCamera();
|
||||||
_lineHeight = entity->getLineHeight();
|
_lineHeight = entity->getLineHeight();
|
||||||
_text = entity->getText();
|
_text = entity->getText();
|
||||||
|
|
|
@ -126,7 +126,10 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
// This work must be done on the main thread
|
// This work must be done on the main thread
|
||||||
if (!hasWebSurface()) {
|
if (!hasWebSurface()) {
|
||||||
buildWebSurface(entity);
|
// If we couldn't create a new web surface, exit
|
||||||
|
if (!buildWebSurface(entity)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_contextPosition != entity->getWorldPosition()) {
|
if (_contextPosition != entity->getWorldPosition()) {
|
||||||
|
@ -146,7 +149,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
||||||
glm::vec2 windowSize = getWindowSize(entity);
|
glm::vec2 windowSize = getWindowSize(entity);
|
||||||
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
||||||
_renderTransform = getModelTransform();
|
_renderTransform = getModelTransform();
|
||||||
_renderTransform.postScale(entity->getDimensions());
|
_renderTransform.postScale(entity->getScaledDimensions());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +193,6 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
||||||
});
|
});
|
||||||
batch.setResourceTexture(0, _texture);
|
batch.setResourceTexture(0, _texture);
|
||||||
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio);
|
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->bindWebBrowserProgram(batch, fadeRatio < OPAQUE_ALPHA_THRESHOLD);
|
DependencyManager::get<GeometryCache>()->bindWebBrowserProgram(batch, fadeRatio < OPAQUE_ALPHA_THRESHOLD);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio), _geometryId);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio), _geometryId);
|
||||||
|
@ -277,7 +279,7 @@ void WebEntityRenderer::destroyWebSurface() {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) const {
|
glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) const {
|
||||||
glm::vec2 dims = glm::vec2(entity->getDimensions());
|
glm::vec2 dims = glm::vec2(entity->getScaledDimensions());
|
||||||
dims *= METERS_TO_INCHES * _lastDPI;
|
dims *= METERS_TO_INCHES * _lastDPI;
|
||||||
|
|
||||||
// ensure no side is never larger then MAX_WINDOW_SIZE
|
// ensure no side is never larger then MAX_WINDOW_SIZE
|
||||||
|
|
|
@ -208,7 +208,7 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
||||||
entity->resetRenderingPropertiesChanged();
|
entity->resetRenderingPropertiesChanged();
|
||||||
_lastPosition = entity->getWorldPosition();
|
_lastPosition = entity->getWorldPosition();
|
||||||
_lastRotation = entity->getWorldOrientation();
|
_lastRotation = entity->getWorldOrientation();
|
||||||
_lastDimensions = entity->getDimensions();
|
_lastDimensions = entity->getScaledDimensions();
|
||||||
|
|
||||||
_keyLightProperties = entity->getKeyLightProperties();
|
_keyLightProperties = entity->getKeyLightProperties();
|
||||||
_skyboxProperties = entity->getSkyboxProperties();
|
_skyboxProperties = entity->getSkyboxProperties();
|
||||||
|
@ -280,7 +280,7 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
|
||||||
if (entity->getWorldPosition() != _lastPosition) {
|
if (entity->getWorldPosition() != _lastPosition) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (entity->getDimensions() != _lastDimensions) {
|
if (entity->getScaledDimensions() != _lastDimensions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (entity->getWorldOrientation() != _lastRotation) {
|
if (entity->getWorldOrientation() != _lastRotation) {
|
||||||
|
|
|
@ -50,6 +50,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||||
{
|
{
|
||||||
setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY);
|
setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY);
|
||||||
setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
|
setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
|
||||||
|
setUnscaledDimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
||||||
// explicitly set transform parts to set dirty flags used by batch rendering
|
// explicitly set transform parts to set dirty flags used by batch rendering
|
||||||
locationChanged();
|
locationChanged();
|
||||||
dimensionsChanged();
|
dimensionsChanged();
|
||||||
|
@ -243,7 +244,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getLocalAngularVelocity());
|
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getLocalAngularVelocity());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration());
|
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration());
|
||||||
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getDimensions());
|
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getUnscaledDimensions());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity());
|
APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_GRAVITY, getGravity());
|
APPEND_ENTITY_PROPERTY(PROP_GRAVITY, getGravity());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_DAMPING, getDamping());
|
APPEND_ENTITY_PROPERTY(PROP_DAMPING, getDamping());
|
||||||
|
@ -779,7 +780,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, customSetAcceleration);
|
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, customSetAcceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setDimensions);
|
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setUnscaledDimensions);
|
||||||
READ_ENTITY_PROPERTY(PROP_DENSITY, float, setDensity);
|
READ_ENTITY_PROPERTY(PROP_DENSITY, float, setDensity);
|
||||||
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, setGravity);
|
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, setGravity);
|
||||||
|
|
||||||
|
@ -898,7 +899,7 @@ void EntityItem::debugDump() const {
|
||||||
qCDebug(entities) << "EntityItem id:" << getEntityItemID();
|
qCDebug(entities) << "EntityItem id:" << getEntityItemID();
|
||||||
qCDebug(entities, " edited ago:%f", (double)getEditedAgo());
|
qCDebug(entities, " edited ago:%f", (double)getEditedAgo());
|
||||||
qCDebug(entities, " position:%f,%f,%f", (double)position.x, (double)position.y, (double)position.z);
|
qCDebug(entities, " position:%f,%f,%f", (double)position.x, (double)position.y, (double)position.z);
|
||||||
qCDebug(entities) << " dimensions:" << getDimensions();
|
qCDebug(entities) << " dimensions:" << getScaledDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust any internal timestamps to fix clock skew for this server
|
// adjust any internal timestamps to fix clock skew for this server
|
||||||
|
@ -923,7 +924,7 @@ void EntityItem::adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSk
|
||||||
}
|
}
|
||||||
|
|
||||||
float EntityItem::computeMass() const {
|
float EntityItem::computeMass() const {
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
return getDensity() * _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
|
return getDensity() * _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +943,7 @@ void EntityItem::setMass(float mass) {
|
||||||
// we must protect the density range to help maintain stability of physics simulation
|
// we must protect the density range to help maintain stability of physics simulation
|
||||||
// therefore this method might not accept the mass that is supplied.
|
// therefore this method might not accept the mass that is supplied.
|
||||||
|
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
float volume = _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
|
float volume = _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
|
||||||
|
|
||||||
// compute new density
|
// compute new density
|
||||||
|
@ -1178,7 +1179,7 @@ bool EntityItem::wantTerseEditLogging() const {
|
||||||
glm::mat4 EntityItem::getEntityToWorldMatrix() const {
|
glm::mat4 EntityItem::getEntityToWorldMatrix() const {
|
||||||
glm::mat4 translation = glm::translate(getWorldPosition());
|
glm::mat4 translation = glm::translate(getWorldPosition());
|
||||||
glm::mat4 rotation = glm::mat4_cast(getWorldOrientation());
|
glm::mat4 rotation = glm::mat4_cast(getWorldOrientation());
|
||||||
glm::mat4 scale = glm::scale(getDimensions());
|
glm::mat4 scale = glm::scale(getScaledDimensions());
|
||||||
glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
||||||
return translation * rotation * scale * registration;
|
return translation * rotation * scale * registration;
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1219,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getDimensions); // NOTE: radius is obsolete
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getUnscaledDimensions);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getLocalOrientation);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getLocalOrientation);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getLocalVelocity);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getLocalVelocity);
|
||||||
|
@ -1326,7 +1327,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(acceleration, setAcceleration);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(acceleration, setAcceleration);
|
||||||
|
|
||||||
// these (along with "position" above) affect tree structure
|
// these (along with "position" above) affect tree structure
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setDimensions);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setUnscaledDimensions);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint);
|
||||||
|
|
||||||
// these (along with all properties above) affect the simulation
|
// these (along with all properties above) affect the simulation
|
||||||
|
@ -1429,7 +1430,7 @@ void EntityItem::recordCreationTime() {
|
||||||
const Transform EntityItem::getTransformToCenter(bool& success) const {
|
const Transform EntityItem::getTransformToCenter(bool& success) const {
|
||||||
Transform result = getTransform(success);
|
Transform result = getTransform(success);
|
||||||
if (getRegistrationPoint() != ENTITY_ITEM_HALF_VEC3) { // If it is not already centered, translate to center
|
if (getRegistrationPoint() != ENTITY_ITEM_HALF_VEC3) { // If it is not already centered, translate to center
|
||||||
result.postTranslate((ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()) * getDimensions()); // Position to center
|
result.postTranslate((ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()) * getScaledDimensions()); // Position to center
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1445,7 +1446,7 @@ AACube EntityItem::getMaximumAACube(bool& success) const {
|
||||||
// we want to compute the furthestExtent that an entity can extend out from its "position"
|
// we want to compute the furthestExtent that an entity can extend out from its "position"
|
||||||
// to do this we compute the max of these two vec3s: registration and 1-registration
|
// to do this we compute the max of these two vec3s: registration and 1-registration
|
||||||
// and then scale by dimensions
|
// and then scale by dimensions
|
||||||
glm::vec3 maxExtents = getDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint);
|
glm::vec3 maxExtents = getScaledDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint);
|
||||||
|
|
||||||
// there exists a sphere that contains maxExtents for all rotations
|
// there exists a sphere that contains maxExtents for all rotations
|
||||||
float radius = glm::length(maxExtents);
|
float radius = glm::length(maxExtents);
|
||||||
|
@ -1470,7 +1471,7 @@ AACube EntityItem::getMinimumAACube(bool& success) const {
|
||||||
glm::vec3 position = getWorldPosition(success);
|
glm::vec3 position = getWorldPosition(success);
|
||||||
if (success) {
|
if (success) {
|
||||||
_recalcMinAACube = false;
|
_recalcMinAACube = false;
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint);
|
glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint);
|
||||||
glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint);
|
glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint);
|
||||||
Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||||
|
@ -1500,7 +1501,7 @@ AABox EntityItem::getAABox(bool& success) const {
|
||||||
glm::vec3 position = getWorldPosition(success);
|
glm::vec3 position = getWorldPosition(success);
|
||||||
if (success) {
|
if (success) {
|
||||||
_recalcAABox = false;
|
_recalcAABox = false;
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint);
|
glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint);
|
||||||
glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint);
|
glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint);
|
||||||
Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||||
|
@ -1540,12 +1541,12 @@ bool EntityItem::shouldPuffQueryAACube() const {
|
||||||
// ... cornerToCornerLength = sqrt(3 x maxDimension ^ 2)
|
// ... cornerToCornerLength = sqrt(3 x maxDimension ^ 2)
|
||||||
// ... radius = sqrt(3 x maxDimension ^ 2) / 2.0f;
|
// ... radius = sqrt(3 x maxDimension ^ 2) / 2.0f;
|
||||||
float EntityItem::getRadius() const {
|
float EntityItem::getRadius() const {
|
||||||
return 0.5f * glm::length(getDimensions());
|
return 0.5f * glm::length(getScaledDimensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const {
|
void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const {
|
||||||
if (_registrationPoint != ENTITY_ITEM_DEFAULT_REGISTRATION_POINT) {
|
if (_registrationPoint != ENTITY_ITEM_DEFAULT_REGISTRATION_POINT) {
|
||||||
glm::mat4 scale = glm::scale(getDimensions());
|
glm::mat4 scale = glm::scale(getScaledDimensions());
|
||||||
glm::mat4 registration = scale * glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
glm::mat4 registration = scale * glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
||||||
glm::vec3 regTransVec = glm::vec3(registration[3]); // extract position component from matrix
|
glm::vec3 regTransVec = glm::vec3(registration[3]); // extract position component from matrix
|
||||||
info.setOffset(regTransVec);
|
info.setOffset(regTransVec);
|
||||||
|
@ -1566,12 +1567,12 @@ bool EntityItem::contains(const glm::vec3& point) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::computeShapeInfo(ShapeInfo& info) {
|
void EntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
info.setParams(getShapeType(), 0.5f * getScaledDimensions());
|
||||||
adjustShapeInfoByRegistration(info);
|
adjustShapeInfoByRegistration(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
float EntityItem::getVolumeEstimate() const {
|
float EntityItem::getVolumeEstimate() const {
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
return dimensions.x * dimensions.y * dimensions.z;
|
return dimensions.x * dimensions.y * dimensions.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1671,11 +1672,21 @@ void EntityItem::setParentID(const QUuid& value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::setDimensions(const glm::vec3& value) {
|
glm::vec3 EntityItem::getScaledDimensions() const {
|
||||||
|
glm::vec3 scale = getSNScale();
|
||||||
|
return _unscaledDimensions * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::setScaledDimensions(const glm::vec3& value) {
|
||||||
|
glm::vec3 parentScale = getSNScale();
|
||||||
|
setUnscaledDimensions(value * parentScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions
|
glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions
|
||||||
if (getDimensions() != newDimensions) {
|
if (getUnscaledDimensions() != newDimensions) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_dimensions = newDimensions;
|
_unscaledDimensions = newDimensions;
|
||||||
});
|
});
|
||||||
locationChanged();
|
locationChanged();
|
||||||
dimensionsChanged();
|
dimensionsChanged();
|
||||||
|
@ -2366,6 +2377,16 @@ void EntityItem::dimensionsChanged() {
|
||||||
somethingChangedNotification();
|
somethingChangedNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityItem::getScalesWithParent() const {
|
||||||
|
// keep this logic the same as in EntityItemProperties::getScalesWithParent
|
||||||
|
if (getClientOnly()) {
|
||||||
|
QUuid ancestorID = findAncestorOfType(NestableType::Avatar);
|
||||||
|
return !ancestorID.isNull();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EntityItem::globalizeProperties(EntityItemProperties& properties, const QString& messageTemplate, const glm::vec3& offset) const {
|
void EntityItem::globalizeProperties(EntityItemProperties& properties, const QString& messageTemplate, const glm::vec3& offset) const {
|
||||||
// TODO -- combine this with convertLocationToScriptSemantics
|
// TODO -- combine this with convertLocationToScriptSemantics
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -2373,7 +2394,7 @@ void EntityItem::globalizeProperties(EntityItemProperties& properties, const QSt
|
||||||
if (success) {
|
if (success) {
|
||||||
properties.setPosition(globalPosition + offset);
|
properties.setPosition(globalPosition + offset);
|
||||||
properties.setRotation(getWorldOrientation());
|
properties.setRotation(getWorldOrientation());
|
||||||
properties.setDimensions(getDimensions());
|
properties.setDimensions(getScaledDimensions());
|
||||||
// Should we do velocities and accelerations, too? This could end up being quite involved, which is why the method exists.
|
// Should we do velocities and accelerations, too? This could end up being quite involved, which is why the method exists.
|
||||||
} else {
|
} else {
|
||||||
properties.setPosition(getQueryAACube().calcCenter() + offset); // best we can do
|
properties.setPosition(getQueryAACube().calcCenter() + offset); // best we can do
|
||||||
|
|
|
@ -180,8 +180,11 @@ public:
|
||||||
void setDescription(const QString& value);
|
void setDescription(const QString& value);
|
||||||
|
|
||||||
/// Dimensions in meters (0.0 - TREE_SCALE)
|
/// Dimensions in meters (0.0 - TREE_SCALE)
|
||||||
inline const glm::vec3 getDimensions() const { return _dimensions; }
|
glm::vec3 getScaledDimensions() const;
|
||||||
virtual void setDimensions(const glm::vec3& value);
|
virtual void setScaledDimensions(const glm::vec3& value);
|
||||||
|
|
||||||
|
inline const glm::vec3 getUnscaledDimensions() const { return _unscaledDimensions; }
|
||||||
|
virtual void setUnscaledDimensions(const glm::vec3& value);
|
||||||
|
|
||||||
float getLocalRenderAlpha() const;
|
float getLocalRenderAlpha() const;
|
||||||
void setLocalRenderAlpha(float localRenderAlpha);
|
void setLocalRenderAlpha(float localRenderAlpha);
|
||||||
|
@ -456,6 +459,8 @@ public:
|
||||||
|
|
||||||
virtual void locationChanged(bool tellPhysics = true) override;
|
virtual void locationChanged(bool tellPhysics = true) override;
|
||||||
|
|
||||||
|
virtual bool getScalesWithParent() const override;
|
||||||
|
|
||||||
using ChangeHandlerCallback = std::function<void(const EntityItemID&)>;
|
using ChangeHandlerCallback = std::function<void(const EntityItemID&)>;
|
||||||
using ChangeHandlerId = QUuid;
|
using ChangeHandlerId = QUuid;
|
||||||
ChangeHandlerId registerChangeHandler(const ChangeHandlerCallback& handler);
|
ChangeHandlerId registerChangeHandler(const ChangeHandlerCallback& handler);
|
||||||
|
@ -477,7 +482,7 @@ protected:
|
||||||
|
|
||||||
virtual void dimensionsChanged() override;
|
virtual void dimensionsChanged() override;
|
||||||
|
|
||||||
glm::vec3 _dimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS };
|
glm::vec3 _unscaledDimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS };
|
||||||
EntityTypes::EntityType _type { EntityTypes::Unknown };
|
EntityTypes::EntityType _type { EntityTypes::Unknown };
|
||||||
quint64 _lastSimulated { 0 }; // last time this entity called simulate(), this includes velocity, angular velocity,
|
quint64 _lastSimulated { 0 }; // last time this entity called simulate(), this includes velocity, angular velocity,
|
||||||
// and physics changes
|
// and physics changes
|
||||||
|
|
|
@ -365,6 +365,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation);
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCAL_VELOCITY, localVelocity);
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_VELOCITY, localVelocity);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_DIMENSIONS, localDimensions);
|
||||||
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed);
|
CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||||
|
@ -628,6 +629,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_VELOCITY, localVelocity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_VELOCITY, localVelocity);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_DIMENSIONS, localDimensions);
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID);
|
||||||
|
@ -805,6 +807,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(localVelocity, glmVec3, setLocalVelocity);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localVelocity, glmVec3, setLocalVelocity);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(localAngularVelocity, glmVec3, setLocalAngularVelocity);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localAngularVelocity, glmVec3, setLocalAngularVelocity);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localDimensions, glmVec3, setLocalDimensions);
|
||||||
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations);
|
||||||
|
@ -953,6 +956,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
||||||
COPY_PROPERTY_IF_CHANGED(localRotation);
|
COPY_PROPERTY_IF_CHANGED(localRotation);
|
||||||
COPY_PROPERTY_IF_CHANGED(localVelocity);
|
COPY_PROPERTY_IF_CHANGED(localVelocity);
|
||||||
COPY_PROPERTY_IF_CHANGED(localAngularVelocity);
|
COPY_PROPERTY_IF_CHANGED(localAngularVelocity);
|
||||||
|
COPY_PROPERTY_IF_CHANGED(localDimensions);
|
||||||
|
|
||||||
COPY_PROPERTY_IF_CHANGED(jointRotationsSet);
|
COPY_PROPERTY_IF_CHANGED(jointRotationsSet);
|
||||||
COPY_PROPERTY_IF_CHANGED(jointRotations);
|
COPY_PROPERTY_IF_CHANGED(jointRotations);
|
||||||
|
@ -1132,6 +1136,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
||||||
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glm::quat);
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glm::quat);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3);
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3);
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glm::vec3);
|
||||||
|
|
||||||
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>);
|
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>);
|
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>);
|
||||||
|
@ -2470,9 +2475,25 @@ bool EntityItemProperties::transformChanged() const {
|
||||||
localPositionChanged() || localRotationChanged();
|
localPositionChanged() || localRotationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityItemProperties::getScalesWithParent() const {
|
||||||
|
// keep this logic the same as in EntityItem::getScalesWithParent
|
||||||
|
bool scalesWithParent { false };
|
||||||
|
if (parentIDChanged()) {
|
||||||
|
bool success;
|
||||||
|
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(getParentID(), success);
|
||||||
|
if (success && parent) {
|
||||||
|
bool avatarAncestor = (parent->getNestableType() == NestableType::Avatar ||
|
||||||
|
parent->hasAncestorOfType(NestableType::Avatar));
|
||||||
|
scalesWithParent = getClientOnly() && avatarAncestor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scalesWithParent;
|
||||||
|
}
|
||||||
|
|
||||||
bool EntityItemProperties::parentRelatedPropertyChanged() const {
|
bool EntityItemProperties::parentRelatedPropertyChanged() const {
|
||||||
return positionChanged() || rotationChanged() ||
|
return positionChanged() || rotationChanged() ||
|
||||||
localPositionChanged() || localRotationChanged() ||
|
localPositionChanged() || localRotationChanged() ||
|
||||||
|
localDimensionsChanged() ||
|
||||||
parentIDChanged() || parentJointIndexChanged();
|
parentIDChanged() || parentJointIndexChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ public:
|
||||||
EntityPropertyFlags getChangedProperties() const;
|
EntityPropertyFlags getChangedProperties() const;
|
||||||
|
|
||||||
bool transformChanged() const;
|
bool transformChanged() const;
|
||||||
|
bool getScalesWithParent() const;
|
||||||
bool parentRelatedPropertyChanged() const;
|
bool parentRelatedPropertyChanged() const;
|
||||||
bool queryAACubeRelatedPropertyChanged() const;
|
bool queryAACubeRelatedPropertyChanged() const;
|
||||||
|
|
||||||
|
@ -227,6 +228,7 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION);
|
DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION);
|
||||||
DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3);
|
DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3);
|
||||||
DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3);
|
DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3);
|
||||||
|
DEFINE_PROPERTY_REF(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glmVec3, ENTITY_ITEM_ZERO_VEC3);
|
||||||
|
|
||||||
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>, QVector<bool>());
|
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>, QVector<bool>());
|
||||||
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>, QVector<glm::quat>());
|
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>, QVector<glm::quat>());
|
||||||
|
|
|
@ -220,6 +220,8 @@ enum EntityPropertyList {
|
||||||
PROP_HAZE_KEYLIGHT_RANGE,
|
PROP_HAZE_KEYLIGHT_RANGE,
|
||||||
PROP_HAZE_KEYLIGHT_ALTITUDE,
|
PROP_HAZE_KEYLIGHT_ALTITUDE,
|
||||||
|
|
||||||
|
PROP_LOCAL_DIMENSIONS, // only used to convert values to and from scripts
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ATTENTION: add new properties to end of list just ABOVE this line
|
// ATTENTION: add new properties to end of list just ABOVE this line
|
||||||
PROP_AFTER_LAST_ITEM,
|
PROP_AFTER_LAST_ITEM,
|
||||||
|
|
|
@ -117,7 +117,8 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties& entitySideProperties) {
|
EntityItemProperties convertPropertiesToScriptSemantics(const EntityItemProperties& entitySideProperties,
|
||||||
|
bool scalesWithParent) {
|
||||||
// In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript,
|
// In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript,
|
||||||
// they are in world-space. The local versions are put into localPosition and localRotation and position and
|
// they are in world-space. The local versions are put into localPosition and localRotation and position and
|
||||||
// rotation are converted from local to world space.
|
// rotation are converted from local to world space.
|
||||||
|
@ -126,35 +127,48 @@ EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties
|
||||||
scriptSideProperties.setLocalRotation(entitySideProperties.getRotation());
|
scriptSideProperties.setLocalRotation(entitySideProperties.getRotation());
|
||||||
scriptSideProperties.setLocalVelocity(entitySideProperties.getLocalVelocity());
|
scriptSideProperties.setLocalVelocity(entitySideProperties.getLocalVelocity());
|
||||||
scriptSideProperties.setLocalAngularVelocity(entitySideProperties.getLocalAngularVelocity());
|
scriptSideProperties.setLocalAngularVelocity(entitySideProperties.getLocalAngularVelocity());
|
||||||
|
scriptSideProperties.setLocalDimensions(entitySideProperties.getDimensions());
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(),
|
glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
scalesWithParent,
|
||||||
success);
|
success);
|
||||||
glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(),
|
glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
scalesWithParent,
|
||||||
success);
|
success);
|
||||||
glm::vec3 worldVelocity = SpatiallyNestable::localToWorldVelocity(entitySideProperties.getVelocity(),
|
glm::vec3 worldVelocity = SpatiallyNestable::localToWorldVelocity(entitySideProperties.getVelocity(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
scalesWithParent,
|
||||||
success);
|
success);
|
||||||
glm::vec3 worldAngularVelocity = SpatiallyNestable::localToWorldAngularVelocity(entitySideProperties.getAngularVelocity(),
|
glm::vec3 worldAngularVelocity = SpatiallyNestable::localToWorldAngularVelocity(entitySideProperties.getAngularVelocity(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
scalesWithParent,
|
||||||
success);
|
success);
|
||||||
|
glm::vec3 worldDimensions = SpatiallyNestable::localToWorldDimensions(entitySideProperties.getDimensions(),
|
||||||
|
entitySideProperties.getParentID(),
|
||||||
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
scalesWithParent,
|
||||||
|
success);
|
||||||
|
|
||||||
|
|
||||||
scriptSideProperties.setPosition(worldPosition);
|
scriptSideProperties.setPosition(worldPosition);
|
||||||
scriptSideProperties.setRotation(worldRotation);
|
scriptSideProperties.setRotation(worldRotation);
|
||||||
scriptSideProperties.setVelocity(worldVelocity);
|
scriptSideProperties.setVelocity(worldVelocity);
|
||||||
scriptSideProperties.setAngularVelocity(worldAngularVelocity);
|
scriptSideProperties.setAngularVelocity(worldAngularVelocity);
|
||||||
|
scriptSideProperties.setDimensions(worldDimensions);
|
||||||
|
|
||||||
return scriptSideProperties;
|
return scriptSideProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperties& scriptSideProperties) {
|
EntityItemProperties convertPropertiesFromScriptSemantics(const EntityItemProperties& scriptSideProperties,
|
||||||
|
bool scalesWithParent) {
|
||||||
// convert position and rotation properties from world-space to local, unless localPosition and localRotation
|
// convert position and rotation properties from world-space to local, unless localPosition and localRotation
|
||||||
// are set. If they are set, they overwrite position and rotation.
|
// are set. If they are set, they overwrite position and rotation.
|
||||||
EntityItemProperties entitySideProperties = scriptSideProperties;
|
EntityItemProperties entitySideProperties = scriptSideProperties;
|
||||||
|
@ -168,7 +182,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
|
||||||
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(),
|
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
success);
|
scalesWithParent, success);
|
||||||
entitySideProperties.setPosition(localPosition);
|
entitySideProperties.setPosition(localPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +192,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
|
||||||
glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(),
|
glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
success);
|
scalesWithParent, success);
|
||||||
entitySideProperties.setRotation(localRotation);
|
entitySideProperties.setRotation(localRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +202,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
|
||||||
glm::vec3 localVelocity = SpatiallyNestable::worldToLocalVelocity(entitySideProperties.getVelocity(),
|
glm::vec3 localVelocity = SpatiallyNestable::worldToLocalVelocity(entitySideProperties.getVelocity(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
success);
|
scalesWithParent, success);
|
||||||
entitySideProperties.setVelocity(localVelocity);
|
entitySideProperties.setVelocity(localVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,10 +213,20 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
|
||||||
SpatiallyNestable::worldToLocalAngularVelocity(entitySideProperties.getAngularVelocity(),
|
SpatiallyNestable::worldToLocalAngularVelocity(entitySideProperties.getAngularVelocity(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex(),
|
entitySideProperties.getParentJointIndex(),
|
||||||
success);
|
scalesWithParent, success);
|
||||||
entitySideProperties.setAngularVelocity(localAngularVelocity);
|
entitySideProperties.setAngularVelocity(localAngularVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scriptSideProperties.localDimensionsChanged()) {
|
||||||
|
entitySideProperties.setDimensions(scriptSideProperties.getLocalDimensions());
|
||||||
|
} else if (scriptSideProperties.dimensionsChanged()) {
|
||||||
|
glm::vec3 localDimensions = SpatiallyNestable::worldToLocalDimensions(entitySideProperties.getDimensions(),
|
||||||
|
entitySideProperties.getParentID(),
|
||||||
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
scalesWithParent, success);
|
||||||
|
entitySideProperties.setDimensions(localDimensions);
|
||||||
|
}
|
||||||
|
|
||||||
return entitySideProperties;
|
return entitySideProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,9 +236,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
||||||
|
|
||||||
_activityTracking.addedEntityCount++;
|
_activityTracking.addedEntityCount++;
|
||||||
|
|
||||||
EntityItemProperties propertiesWithSimID = convertLocationFromScriptSemantics(properties);
|
EntityItemProperties propertiesWithSimID = properties;
|
||||||
propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged());
|
|
||||||
|
|
||||||
if (clientOnly) {
|
if (clientOnly) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
const QUuid myNodeID = nodeList->getSessionUUID();
|
const QUuid myNodeID = nodeList->getSessionUUID();
|
||||||
|
@ -222,6 +244,11 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
||||||
propertiesWithSimID.setOwningAvatarID(myNodeID);
|
propertiesWithSimID.setOwningAvatarID(myNodeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool scalesWithParent = propertiesWithSimID.getScalesWithParent();
|
||||||
|
|
||||||
|
propertiesWithSimID = convertPropertiesFromScriptSemantics(propertiesWithSimID, scalesWithParent);
|
||||||
|
propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged());
|
||||||
|
|
||||||
auto dimensions = propertiesWithSimID.getDimensions();
|
auto dimensions = propertiesWithSimID.getDimensions();
|
||||||
float volume = dimensions.x * dimensions.y * dimensions.z;
|
float volume = dimensions.x * dimensions.y * dimensions.z;
|
||||||
auto density = propertiesWithSimID.getDensity();
|
auto density = propertiesWithSimID.getDensity();
|
||||||
|
@ -295,15 +322,20 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
||||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) {
|
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
|
bool scalesWithParent { false };
|
||||||
EntityItemProperties results;
|
EntityItemProperties results;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->withReadLock([&] {
|
_entityTree->withReadLock([&] {
|
||||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
||||||
if (entity) {
|
if (entity) {
|
||||||
|
scalesWithParent = entity->getScalesWithParent();
|
||||||
if (desiredProperties.getHasProperty(PROP_POSITION) ||
|
if (desiredProperties.getHasProperty(PROP_POSITION) ||
|
||||||
desiredProperties.getHasProperty(PROP_ROTATION) ||
|
desiredProperties.getHasProperty(PROP_ROTATION) ||
|
||||||
desiredProperties.getHasProperty(PROP_LOCAL_POSITION) ||
|
desiredProperties.getHasProperty(PROP_LOCAL_POSITION) ||
|
||||||
desiredProperties.getHasProperty(PROP_LOCAL_ROTATION)) {
|
desiredProperties.getHasProperty(PROP_LOCAL_ROTATION) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_VELOCITY) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_ANGULAR_VELOCITY) ||
|
||||||
|
desiredProperties.getHasProperty(PROP_LOCAL_DIMENSIONS)) {
|
||||||
// if we are explicitly getting position or rotation, we need parent information to make sense of them.
|
// if we are explicitly getting position or rotation, we need parent information to make sense of them.
|
||||||
desiredProperties.setHasProperty(PROP_PARENT_ID);
|
desiredProperties.setHasProperty(PROP_PARENT_ID);
|
||||||
desiredProperties.setHasProperty(PROP_PARENT_JOINT_INDEX);
|
desiredProperties.setHasProperty(PROP_PARENT_JOINT_INDEX);
|
||||||
|
@ -316,6 +348,9 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
||||||
desiredProperties = entity->getEntityProperties(params);
|
desiredProperties = entity->getEntityProperties(params);
|
||||||
desiredProperties.setHasProperty(PROP_LOCAL_POSITION);
|
desiredProperties.setHasProperty(PROP_LOCAL_POSITION);
|
||||||
desiredProperties.setHasProperty(PROP_LOCAL_ROTATION);
|
desiredProperties.setHasProperty(PROP_LOCAL_ROTATION);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_VELOCITY);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_ANGULAR_VELOCITY);
|
||||||
|
desiredProperties.setHasProperty(PROP_LOCAL_DIMENSIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
results = entity->getProperties(desiredProperties);
|
results = entity->getProperties(desiredProperties);
|
||||||
|
@ -323,7 +358,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertLocationToScriptSemantics(results);
|
return convertPropertiesToScriptSemantics(results, scalesWithParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) {
|
QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) {
|
||||||
|
@ -390,10 +425,13 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
||||||
if (!scriptSideProperties.localRotationChanged() && !scriptSideProperties.rotationChanged()) {
|
if (!scriptSideProperties.localRotationChanged() && !scriptSideProperties.rotationChanged()) {
|
||||||
properties.setRotation(entity->getWorldOrientation());
|
properties.setRotation(entity->getWorldOrientation());
|
||||||
}
|
}
|
||||||
|
if (!scriptSideProperties.localDimensionsChanged() && !scriptSideProperties.dimensionsChanged()) {
|
||||||
|
properties.setDimensions(entity->getScaledDimensions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
properties = convertLocationFromScriptSemantics(properties);
|
|
||||||
properties.setClientOnly(entity->getClientOnly());
|
properties.setClientOnly(entity->getClientOnly());
|
||||||
properties.setOwningAvatarID(entity->getOwningAvatarID());
|
properties.setOwningAvatarID(entity->getOwningAvatarID());
|
||||||
|
properties = convertPropertiesFromScriptSemantics(properties, properties.getScalesWithParent());
|
||||||
|
|
||||||
float cost = calculateCost(density * volume, oldVelocity, newVelocity);
|
float cost = calculateCost(density * volume, oldVelocity, newVelocity);
|
||||||
cost *= costMultiplier;
|
cost *= costMultiplier;
|
||||||
|
@ -529,7 +567,7 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dimensions = entity->getDimensions();
|
auto dimensions = entity->getScaledDimensions();
|
||||||
float volume = dimensions.x * dimensions.y * dimensions.z;
|
float volume = dimensions.x * dimensions.y * dimensions.z;
|
||||||
auto density = entity->getDensity();
|
auto density = entity->getDensity();
|
||||||
auto velocity = entity->getWorldVelocity().length();
|
auto velocity = entity->getWorldVelocity().length();
|
||||||
|
|
|
@ -667,7 +667,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
||||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||||
|
|
||||||
glm::vec3 dimensions = entity->getDimensions();
|
glm::vec3 dimensions = entity->getScaledDimensions();
|
||||||
glm::vec3 registrationPoint = entity->getRegistrationPoint();
|
glm::vec3 registrationPoint = entity->getRegistrationPoint();
|
||||||
glm::vec3 corner = -(dimensions * registrationPoint);
|
glm::vec3 corner = -(dimensions * registrationPoint);
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc
|
||||||
glm::vec3 penetration;
|
glm::vec3 penetration;
|
||||||
if (!success || entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) {
|
if (!success || entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) {
|
||||||
|
|
||||||
glm::vec3 dimensions = entity->getDimensions();
|
glm::vec3 dimensions = entity->getScaledDimensions();
|
||||||
|
|
||||||
// FIXME - consider allowing the entity to determine penetration so that
|
// FIXME - consider allowing the entity to determine penetration so that
|
||||||
// entities could presumably dull actuall hull testing if they wanted to
|
// entities could presumably dull actuall hull testing if they wanted to
|
||||||
|
|
|
@ -41,16 +41,16 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID) : EntityItem(
|
||||||
_color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0;
|
_color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightEntityItem::setDimensions(const glm::vec3& value) {
|
void LightEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
if (_isSpotlight) {
|
if (_isSpotlight) {
|
||||||
// If we are a spotlight, treat the z value as our radius or length, and
|
// If we are a spotlight, treat the z value as our radius or length, and
|
||||||
// recalculate the x/y dimensions to properly encapsulate the spotlight.
|
// recalculate the x/y dimensions to properly encapsulate the spotlight.
|
||||||
const float length = value.z;
|
const float length = value.z;
|
||||||
const float width = length * glm::sin(glm::radians(_cutoff));
|
const float width = length * glm::sin(glm::radians(_cutoff));
|
||||||
EntityItem::setDimensions(glm::vec3(width, width, length));
|
EntityItem::setUnscaledDimensions(glm::vec3(width, width, length));
|
||||||
} else {
|
} else {
|
||||||
float maxDimension = glm::compMax(value);
|
float maxDimension = glm::compMax(value);
|
||||||
EntityItem::setDimensions(glm::vec3(maxDimension, maxDimension, maxDimension));
|
EntityItem::setUnscaledDimensions(glm::vec3(maxDimension, maxDimension, maxDimension));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void LightEntityItem::setIsSpotlight(bool value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 newDimensions;
|
glm::vec3 newDimensions;
|
||||||
if (value) {
|
if (value) {
|
||||||
const float length = dimensions.z;
|
const float length = dimensions.z;
|
||||||
|
@ -112,7 +112,7 @@ void LightEntityItem::setIsSpotlight(bool value) {
|
||||||
_isSpotlight = value;
|
_isSpotlight = value;
|
||||||
_lightPropertiesChanged = true;
|
_lightPropertiesChanged = true;
|
||||||
});
|
});
|
||||||
setDimensions(newDimensions);
|
setScaledDimensions(newDimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightEntityItem::setCutoff(float value) {
|
void LightEntityItem::setCutoff(float value) {
|
||||||
|
@ -128,9 +128,9 @@ void LightEntityItem::setCutoff(float value) {
|
||||||
if (getIsSpotlight()) {
|
if (getIsSpotlight()) {
|
||||||
// If we are a spotlight, adjusting the cutoff will affect the area we encapsulate,
|
// If we are a spotlight, adjusting the cutoff will affect the area we encapsulate,
|
||||||
// so update the dimensions to reflect this.
|
// so update the dimensions to reflect this.
|
||||||
const float length = getDimensions().z;
|
const float length = getScaledDimensions().z;
|
||||||
const float width = length * glm::sin(glm::radians(_cutoff));
|
const float width = length * glm::sin(glm::radians(_cutoff));
|
||||||
setDimensions(glm::vec3(width, width, length));
|
setScaledDimensions(glm::vec3(width, width, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
||||||
virtual void setDimensions(const glm::vec3& value) override;
|
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
|
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
virtual bool setSubClassProperties(const EntityItemProperties& properties) override;
|
virtual bool setSubClassProperties(const EntityItemProperties& properties) override;
|
||||||
|
|
|
@ -80,7 +80,7 @@ bool LineEntityItem::appendPoint(const glm::vec3& point) {
|
||||||
qCDebug(entities) << "MAX POINTS REACHED!";
|
qCDebug(entities) << "MAX POINTS REACHED!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
glm::vec3 halfBox = getDimensions() * 0.5f;
|
glm::vec3 halfBox = getScaledDimensions() * 0.5f;
|
||||||
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
||||||
qCDebug(entities) << "Point is outside entity's bounding box";
|
qCDebug(entities) << "Point is outside entity's bounding box";
|
||||||
return false;
|
return false;
|
||||||
|
@ -96,7 +96,7 @@ bool LineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
||||||
if (points.size() > MAX_POINTS_PER_LINE) {
|
if (points.size() > MAX_POINTS_PER_LINE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
glm::vec3 halfBox = getDimensions() * 0.5f;
|
glm::vec3 halfBox = getScaledDimensions() * 0.5f;
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
glm::vec3 point = points.at(i);
|
glm::vec3 point = points.at(i);
|
||||||
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
||||||
|
@ -157,7 +157,7 @@ void LineEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << " LINE EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
qCDebug(entities) << " LINE EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||||
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
||||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,7 +289,7 @@ void ModelEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << "ModelEntityItem id:" << getEntityItemID();
|
qCDebug(entities) << "ModelEntityItem id:" << getEntityItemID();
|
||||||
qCDebug(entities) << " edited ago:" << getEditedAgo();
|
qCDebug(entities) << " edited ago:" << getEditedAgo();
|
||||||
qCDebug(entities) << " position:" << getWorldPosition();
|
qCDebug(entities) << " position:" << getWorldPosition();
|
||||||
qCDebug(entities) << " dimensions:" << getDimensions();
|
qCDebug(entities) << " dimensions:" << getScaledDimensions();
|
||||||
qCDebug(entities) << " model URL:" << getModelURL();
|
qCDebug(entities) << " model URL:" << getModelURL();
|
||||||
qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL();
|
qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL();
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,7 +353,7 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() {
|
||||||
float maxDistanceValue = glm::compMax(maxDistance);
|
float maxDistanceValue = glm::compMax(maxDistance);
|
||||||
//times 2 because dimensions are diameters not radii
|
//times 2 because dimensions are diameters not radii
|
||||||
glm::vec3 dims(2.0f * maxDistanceValue);
|
glm::vec3 dims(2.0f * maxDistanceValue);
|
||||||
EntityItem::setDimensions(dims);
|
EntityItem::setScaledDimensions(dims);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ void ParticleEffectEntityItem::debugDump() const {
|
||||||
_particleProperties.color.gradient.target.green << "," <<
|
_particleProperties.color.gradient.target.green << "," <<
|
||||||
_particleProperties.color.gradient.target.blue;
|
_particleProperties.color.gradient.target.blue;
|
||||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ void PolyLineEntityItem::calculateScaleAndRegistrationPoint() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if Polyline has only one or fewer points, use default dimension settings
|
// if Polyline has only one or fewer points, use default dimension settings
|
||||||
setDimensions(newScale);
|
setScaledDimensions(newScale);
|
||||||
EntityItem::setRegistrationPoint(newRegistrationPoint);
|
EntityItem::setRegistrationPoint(newRegistrationPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ void PolyLineEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||||
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
||||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,7 @@ void PolyVoxEntityItem::debugDump() const {
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
qCDebug(entities) << " POLYVOX EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
qCDebug(entities) << " POLYVOX EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ EntityItemID PolyVoxEntityItem::getZPNeighborID() const {
|
||||||
glm::vec3 PolyVoxEntityItem::getSurfacePositionAdjustment() const {
|
glm::vec3 PolyVoxEntityItem::getSurfacePositionAdjustment() const {
|
||||||
glm::vec3 result;
|
glm::vec3 result;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units
|
glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units
|
||||||
if (isEdged()) {
|
if (isEdged()) {
|
||||||
result = scale / -2.0f;
|
result = scale / -2.0f;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +392,7 @@ glm::mat4 PolyVoxEntityItem::voxelToLocalMatrix() const {
|
||||||
voxelVolumeSize = _voxelVolumeSize;
|
voxelVolumeSize = _voxelVolumeSize;
|
||||||
});
|
});
|
||||||
|
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
|
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
|
||||||
bool success; // TODO -- Does this actually have to happen in world space?
|
bool success; // TODO -- Does this actually have to happen in world space?
|
||||||
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes
|
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes
|
||||||
|
|
|
@ -106,11 +106,11 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) {
|
||||||
break;
|
break;
|
||||||
case entity::Shape::Circle:
|
case entity::Shape::Circle:
|
||||||
// Circle is implicitly flat so we enforce flat dimensions
|
// Circle is implicitly flat so we enforce flat dimensions
|
||||||
setDimensions(getDimensions());
|
setUnscaledDimensions(getUnscaledDimensions());
|
||||||
break;
|
break;
|
||||||
case entity::Shape::Quad:
|
case entity::Shape::Quad:
|
||||||
// Quad is implicitly flat so we enforce flat dimensions
|
// Quad is implicitly flat so we enforce flat dimensions
|
||||||
setDimensions(getDimensions());
|
setUnscaledDimensions(getUnscaledDimensions());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_type = EntityTypes::Shape;
|
_type = EntityTypes::Shape;
|
||||||
|
@ -204,15 +204,15 @@ void ShapeEntityItem::setColor(const QColor& value) {
|
||||||
setAlpha(value.alpha());
|
setAlpha(value.alpha());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapeEntityItem::setDimensions(const glm::vec3& value) {
|
void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
const float MAX_FLAT_DIMENSION = 0.0001f;
|
const float MAX_FLAT_DIMENSION = 0.0001f;
|
||||||
if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) {
|
if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) {
|
||||||
// enforce flatness in Y
|
// enforce flatness in Y
|
||||||
glm::vec3 newDimensions = value;
|
glm::vec3 newDimensions = value;
|
||||||
newDimensions.y = MAX_FLAT_DIMENSION;
|
newDimensions.y = MAX_FLAT_DIMENSION;
|
||||||
EntityItem::setDimensions(newDimensions);
|
EntityItem::setUnscaledDimensions(newDimensions);
|
||||||
} else {
|
} else {
|
||||||
EntityItem::setDimensions(value);
|
EntityItem::setUnscaledDimensions(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ void ShapeEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << " collisionShapeType:" << ShapeInfo::getNameForShapeType(getShapeType());
|
qCDebug(entities) << " collisionShapeType:" << ShapeInfo::getNameForShapeType(getShapeType());
|
||||||
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
||||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
qCDebug(entities) << "SHAPE EntityItem Ptr:" << this;
|
qCDebug(entities) << "SHAPE EntityItem Ptr:" << this;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
// This will be called whenever DIRTY_SHAPE flag (set by dimension change, etc)
|
// This will be called whenever DIRTY_SHAPE flag (set by dimension change, etc)
|
||||||
// is set.
|
// is set.
|
||||||
|
|
||||||
const glm::vec3 entityDimensions = getDimensions();
|
const glm::vec3 entityDimensions = getScaledDimensions();
|
||||||
|
|
||||||
switch (_shape){
|
switch (_shape){
|
||||||
case entity::Shape::Quad:
|
case entity::Shape::Quad:
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
const rgbColor& getColor() const { return _color; }
|
const rgbColor& getColor() const { return _color; }
|
||||||
void setColor(const rgbColor& value);
|
void setColor(const rgbColor& value);
|
||||||
|
|
||||||
void setDimensions(const glm::vec3& value) override;
|
void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
|
|
||||||
xColor getXColor() const;
|
xColor getXColor() const;
|
||||||
void setColor(const xColor& value);
|
void setColor(const xColor& value);
|
||||||
|
|
|
@ -41,9 +41,9 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID) : EntityItem(en
|
||||||
|
|
||||||
const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
|
const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
|
||||||
|
|
||||||
void TextEntityItem::setDimensions(const glm::vec3& value) {
|
void TextEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
// NOTE: Text Entities always have a "depth" of 1cm.
|
// NOTE: Text Entities always have a "depth" of 1cm.
|
||||||
EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
|
EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties TextEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties TextEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
|
@ -132,7 +132,7 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
void** intersectedObject, bool precisionPicking) const {
|
void** intersectedObject, bool precisionPicking) const {
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||||
glm::quat rotation = getWorldOrientation();
|
glm::quat rotation = getWorldOrientation();
|
||||||
glm::vec3 position = getWorldPosition() + rotation *
|
glm::vec3 position = getWorldPosition() + rotation *
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
||||||
virtual void setDimensions(const glm::vec3& value) override;
|
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
|
|
|
@ -36,9 +36,9 @@ WebEntityItem::WebEntityItem(const EntityItemID& entityItemID) : EntityItem(enti
|
||||||
|
|
||||||
const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
|
const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
|
||||||
|
|
||||||
void WebEntityItem::setDimensions(const glm::vec3& value) {
|
void WebEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
// NOTE: Web Entities always have a "depth" of 1cm.
|
// NOTE: Web Entities always have a "depth" of 1cm.
|
||||||
EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
|
EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties WebEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties WebEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
|
@ -109,7 +109,7 @@ bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const g
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
void** intersectedObject, bool precisionPicking) const {
|
void** intersectedObject, bool precisionPicking) const {
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||||
glm::quat rotation = getWorldOrientation();
|
glm::quat rotation = getWorldOrientation();
|
||||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
||||||
virtual void setDimensions(const glm::vec3& value) override;
|
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
|
|
|
@ -242,7 +242,7 @@ void ZoneEntityItem::debugDump() const {
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||||
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
||||||
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode);
|
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode);
|
||||||
|
|
|
@ -605,6 +605,10 @@ void GLBackend::do_glColor4f(const Batch& batch, size_t paramOffset) {
|
||||||
if (_input._colorAttribute != newColor) {
|
if (_input._colorAttribute != newColor) {
|
||||||
_input._colorAttribute = newColor;
|
_input._colorAttribute = newColor;
|
||||||
glVertexAttrib4fv(gpu::Stream::COLOR, &_input._colorAttribute.r);
|
glVertexAttrib4fv(gpu::Stream::COLOR, &_input._colorAttribute.r);
|
||||||
|
// Color has been changed and is not white. To prevent colors from bleeding
|
||||||
|
// between different objects, we need to set the _hadColorAttribute flag
|
||||||
|
// as if a previous render call had potential colors
|
||||||
|
_input._hadColorAttribute = (newColor != glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,7 @@ protected:
|
||||||
|
|
||||||
struct InputStageState {
|
struct InputStageState {
|
||||||
bool _invalidFormat { true };
|
bool _invalidFormat { true };
|
||||||
|
bool _hadColorAttribute{ true };
|
||||||
Stream::FormatPointer _format;
|
Stream::FormatPointer _format;
|
||||||
std::string _formatKey;
|
std::string _formatKey;
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,8 @@ void GL41Backend::updateInput() {
|
||||||
|
|
||||||
// now we need to bind the buffers and assign the attrib pointers
|
// now we need to bind the buffers and assign the attrib pointers
|
||||||
if (_input._format) {
|
if (_input._format) {
|
||||||
|
bool hasColorAttribute{ false };
|
||||||
|
|
||||||
const Buffers& buffers = _input._buffers;
|
const Buffers& buffers = _input._buffers;
|
||||||
const Offsets& offsets = _input._bufferOffsets;
|
const Offsets& offsets = _input._bufferOffsets;
|
||||||
const Offsets& strides = _input._bufferStrides;
|
const Offsets& strides = _input._bufferStrides;
|
||||||
|
@ -98,6 +100,8 @@ void GL41Backend::updateInput() {
|
||||||
uintptr_t pointer = (uintptr_t)(attrib._offset + offsets[bufferNum]);
|
uintptr_t pointer = (uintptr_t)(attrib._offset + offsets[bufferNum]);
|
||||||
GLboolean isNormalized = attrib._element.isNormalized();
|
GLboolean isNormalized = attrib._element.isNormalized();
|
||||||
|
|
||||||
|
hasColorAttribute = hasColorAttribute || (slot == Stream::COLOR);
|
||||||
|
|
||||||
for (size_t locNum = 0; locNum < locationCount; ++locNum) {
|
for (size_t locNum = 0; locNum < locationCount; ++locNum) {
|
||||||
if (attrib._element.isInteger()) {
|
if (attrib._element.isInteger()) {
|
||||||
glVertexAttribIPointer(slot + (GLuint)locNum, count, type, stride,
|
glVertexAttribIPointer(slot + (GLuint)locNum, count, type, stride,
|
||||||
|
@ -117,6 +121,15 @@ void GL41Backend::updateInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_input._hadColorAttribute && !hasColorAttribute) {
|
||||||
|
// The previous input stage had a color attribute but this one doesn't so reset
|
||||||
|
// color to pure white.
|
||||||
|
const auto white = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
glVertexAttrib4fv(Stream::COLOR, &white.r);
|
||||||
|
_input._colorAttribute = white;
|
||||||
|
}
|
||||||
|
_input._hadColorAttribute = hasColorAttribute;
|
||||||
}
|
}
|
||||||
// everything format related should be in sync now
|
// everything format related should be in sync now
|
||||||
_input._invalidFormat = false;
|
_input._invalidFormat = false;
|
||||||
|
|
|
@ -32,6 +32,8 @@ void GL45Backend::updateInput() {
|
||||||
|
|
||||||
// Assign the vertex format required
|
// Assign the vertex format required
|
||||||
if (_input._format) {
|
if (_input._format) {
|
||||||
|
bool hasColorAttribute{ false };
|
||||||
|
|
||||||
_input._attribBindingBuffers.reset();
|
_input._attribBindingBuffers.reset();
|
||||||
|
|
||||||
const Stream::Format::AttributeMap& attributes = _input._format->getAttributes();
|
const Stream::Format::AttributeMap& attributes = _input._format->getAttributes();
|
||||||
|
@ -54,6 +56,9 @@ void GL45Backend::updateInput() {
|
||||||
GLboolean isNormalized = attrib._element.isNormalized();
|
GLboolean isNormalized = attrib._element.isNormalized();
|
||||||
|
|
||||||
GLenum perLocationSize = attrib._element.getLocationSize();
|
GLenum perLocationSize = attrib._element.getLocationSize();
|
||||||
|
|
||||||
|
hasColorAttribute = hasColorAttribute || (slot == Stream::COLOR);
|
||||||
|
|
||||||
for (GLuint locNum = 0; locNum < locationCount; ++locNum) {
|
for (GLuint locNum = 0; locNum < locationCount; ++locNum) {
|
||||||
GLuint attriNum = (GLuint)(slot + locNum);
|
GLuint attriNum = (GLuint)(slot + locNum);
|
||||||
newActivation.set(attriNum);
|
newActivation.set(attriNum);
|
||||||
|
@ -84,6 +89,15 @@ void GL45Backend::updateInput() {
|
||||||
glVertexBindingDivisor(bufferChannelNum, frequency);
|
glVertexBindingDivisor(bufferChannelNum, frequency);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_input._hadColorAttribute && !hasColorAttribute) {
|
||||||
|
// The previous input stage had a color attribute but this one doesn't so reset
|
||||||
|
// color to pure white.
|
||||||
|
const auto white = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
glVertexAttrib4fv(Stream::COLOR, &white.r);
|
||||||
|
_input._colorAttribute = white;
|
||||||
|
}
|
||||||
|
_input._hadColorAttribute = hasColorAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manage Activation what was and what is expected now
|
// Manage Activation what was and what is expected now
|
||||||
|
|
|
@ -89,17 +89,19 @@ void UserActivityLoggerScriptingInterface::doLogAction(QString action, QJsonObje
|
||||||
Q_ARG(QJsonObject, details));
|
Q_ARG(QJsonObject, details));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserActivityLoggerScriptingInterface::commercePurchaseSuccess(QString marketplaceID, int cost, bool firstPurchaseOfThisItem) {
|
void UserActivityLoggerScriptingInterface::commercePurchaseSuccess(QString marketplaceID, QString contentCreator, int cost, bool firstPurchaseOfThisItem) {
|
||||||
QJsonObject payload;
|
QJsonObject payload;
|
||||||
payload["marketplaceID"] = marketplaceID;
|
payload["marketplaceID"] = marketplaceID;
|
||||||
|
payload["contentCreator"] = contentCreator;
|
||||||
payload["cost"] = cost;
|
payload["cost"] = cost;
|
||||||
payload["firstPurchaseOfThisItem"] = firstPurchaseOfThisItem;
|
payload["firstPurchaseOfThisItem"] = firstPurchaseOfThisItem;
|
||||||
doLogAction("commercePurchaseSuccess", payload);
|
doLogAction("commercePurchaseSuccess", payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserActivityLoggerScriptingInterface::commercePurchaseFailure(QString marketplaceID, int cost, bool firstPurchaseOfThisItem, QString errorDetails) {
|
void UserActivityLoggerScriptingInterface::commercePurchaseFailure(QString marketplaceID, QString contentCreator, int cost, bool firstPurchaseOfThisItem, QString errorDetails) {
|
||||||
QJsonObject payload;
|
QJsonObject payload;
|
||||||
payload["marketplaceID"] = marketplaceID;
|
payload["marketplaceID"] = marketplaceID;
|
||||||
|
payload["contentCreator"] = contentCreator;
|
||||||
payload["cost"] = cost;
|
payload["cost"] = cost;
|
||||||
payload["firstPurchaseOfThisItem"] = firstPurchaseOfThisItem;
|
payload["firstPurchaseOfThisItem"] = firstPurchaseOfThisItem;
|
||||||
payload["errorDetails"] = errorDetails;
|
payload["errorDetails"] = errorDetails;
|
||||||
|
|
|
@ -33,8 +33,8 @@ public:
|
||||||
Q_INVOKABLE void bubbleToggled(bool newValue);
|
Q_INVOKABLE void bubbleToggled(bool newValue);
|
||||||
Q_INVOKABLE void bubbleActivated();
|
Q_INVOKABLE void bubbleActivated();
|
||||||
Q_INVOKABLE void logAction(QString action, QVariantMap details = QVariantMap{});
|
Q_INVOKABLE void logAction(QString action, QVariantMap details = QVariantMap{});
|
||||||
Q_INVOKABLE void commercePurchaseSuccess(QString marketplaceID, int cost, bool firstPurchaseOfThisItem);
|
Q_INVOKABLE void commercePurchaseSuccess(QString marketplaceID, QString contentCreator, int cost, bool firstPurchaseOfThisItem);
|
||||||
Q_INVOKABLE void commercePurchaseFailure(QString marketplaceID, int cost, bool firstPurchaseOfThisItem, QString errorDetails);
|
Q_INVOKABLE void commercePurchaseFailure(QString marketplaceID, QString contentCreator, int cost, bool firstPurchaseOfThisItem, QString errorDetails);
|
||||||
Q_INVOKABLE void commerceEntityRezzed(QString marketplaceID, QString source, QString type);
|
Q_INVOKABLE void commerceEntityRezzed(QString marketplaceID, QString source, QString type);
|
||||||
Q_INVOKABLE void commerceWalletSetupStarted(int timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain);
|
Q_INVOKABLE void commerceWalletSetupStarted(int timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain);
|
||||||
Q_INVOKABLE void commerceWalletSetupProgress(int timestamp, QString setupAttemptID, int secondsElapsed, int currentStepNumber, QString currentStepName);
|
Q_INVOKABLE void commerceWalletSetupProgress(int timestamp, QString setupAttemptID, int secondsElapsed, int currentStepNumber, QString currentStepName);
|
||||||
|
|
|
@ -191,6 +191,8 @@ void Connection::queueReceivedMessagePacket(std::unique_ptr<Packet> packet) {
|
||||||
|
|
||||||
pendingMessage.enqueuePacket(std::move(packet));
|
pendingMessage.enqueuePacket(std::move(packet));
|
||||||
|
|
||||||
|
bool processedLastOrOnly = false;
|
||||||
|
|
||||||
while (pendingMessage.hasAvailablePackets()) {
|
while (pendingMessage.hasAvailablePackets()) {
|
||||||
auto packet = pendingMessage.removeNextPacket();
|
auto packet = pendingMessage.removeNextPacket();
|
||||||
|
|
||||||
|
@ -201,9 +203,13 @@ void Connection::queueReceivedMessagePacket(std::unique_ptr<Packet> packet) {
|
||||||
// if this was the last or only packet, then we can remove the pending message from our hash
|
// if this was the last or only packet, then we can remove the pending message from our hash
|
||||||
if (packetPosition == Packet::PacketPosition::LAST ||
|
if (packetPosition == Packet::PacketPosition::LAST ||
|
||||||
packetPosition == Packet::PacketPosition::ONLY) {
|
packetPosition == Packet::PacketPosition::ONLY) {
|
||||||
_pendingReceivedMessages.erase(messageNumber);
|
processedLastOrOnly = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (processedLastOrOnly) {
|
||||||
|
_pendingReceivedMessages.erase(messageNumber);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::sync() {
|
void Connection::sync() {
|
||||||
|
|
|
@ -197,7 +197,7 @@ uint qHash(const PacketType& key, uint seed);
|
||||||
QDebug operator<<(QDebug debug, const PacketType& type);
|
QDebug operator<<(QDebug debug, const PacketType& type);
|
||||||
|
|
||||||
enum class EntityVersion : PacketVersion {
|
enum class EntityVersion : PacketVersion {
|
||||||
StrokeColorProperty = 77,
|
StrokeColorProperty = 0,
|
||||||
HasDynamicOwnershipTests,
|
HasDynamicOwnershipTests,
|
||||||
HazeEffect,
|
HazeEffect,
|
||||||
StaticCertJsonVersionOne,
|
StaticCertJsonVersionOne,
|
||||||
|
|
|
@ -40,17 +40,7 @@ void CauterizedMeshPartPayload::updateTransformForCauterizedMesh(const Transform
|
||||||
|
|
||||||
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const {
|
void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const {
|
||||||
// Still relying on the raw data from the model
|
// Still relying on the raw data from the model
|
||||||
bool useCauterizedMesh = (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE);
|
bool useCauterizedMesh = (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE && renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) && _enableCauterization;
|
||||||
if (useCauterizedMesh) {
|
|
||||||
ModelPointer model = _model.lock();
|
|
||||||
if (model) {
|
|
||||||
CauterizedModel* skeleton = static_cast<CauterizedModel*>(model.get());
|
|
||||||
useCauterizedMesh = useCauterizedMesh && skeleton->getEnableCauterization();
|
|
||||||
} else {
|
|
||||||
useCauterizedMesh = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useCauterizedMesh) {
|
if (useCauterizedMesh) {
|
||||||
if (_cauterizedClusterBuffer) {
|
if (_cauterizedClusterBuffer) {
|
||||||
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, _cauterizedClusterBuffer);
|
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, _cauterizedClusterBuffer);
|
||||||
|
|
|
@ -21,9 +21,12 @@ public:
|
||||||
|
|
||||||
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
||||||
|
|
||||||
|
void setEnableCauterization(bool enableCauterization) { _enableCauterization = enableCauterization; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gpu::BufferPointer _cauterizedClusterBuffer;
|
gpu::BufferPointer _cauterizedClusterBuffer;
|
||||||
Transform _cauterizedTransform;
|
Transform _cauterizedTransform;
|
||||||
|
bool _enableCauterization { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_CauterizedMeshPartPayload_h
|
#endif // hifi_CauterizedMeshPartPayload_h
|
||||||
|
|
|
@ -178,6 +178,12 @@ void CauterizedModel::updateRenderItems() {
|
||||||
modelTransform.setTranslation(self->getTranslation());
|
modelTransform.setTranslation(self->getTranslation());
|
||||||
modelTransform.setRotation(self->getRotation());
|
modelTransform.setRotation(self->getRotation());
|
||||||
|
|
||||||
|
bool isWireframe = self->isWireframe();
|
||||||
|
bool isVisible = self->isVisible();
|
||||||
|
bool isLayeredInFront = self->isLayeredInFront();
|
||||||
|
bool isLayeredInHUD = self->isLayeredInHUD();
|
||||||
|
bool enableCauterization = self->getEnableCauterization();
|
||||||
|
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
for (int i = 0; i < (int)self->_modelMeshRenderItemIDs.size(); i++) {
|
for (int i = 0; i < (int)self->_modelMeshRenderItemIDs.size(); i++) {
|
||||||
|
|
||||||
|
@ -186,7 +192,10 @@ void CauterizedModel::updateRenderItems() {
|
||||||
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
||||||
auto clusterMatricesCauterized(self->getCauterizeMeshState(meshIndex).clusterMatrices);
|
auto clusterMatricesCauterized(self->getCauterizeMeshState(meshIndex).clusterMatrices);
|
||||||
|
|
||||||
transaction.updateItem<CauterizedMeshPartPayload>(itemID, [modelTransform, clusterMatrices, clusterMatricesCauterized](CauterizedMeshPartPayload& data) {
|
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
|
|
||||||
|
transaction.updateItem<CauterizedMeshPartPayload>(itemID, [modelTransform, clusterMatrices, clusterMatricesCauterized, invalidatePayloadShapeKey,
|
||||||
|
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD, enableCauterization](CauterizedMeshPartPayload& data) {
|
||||||
data.updateClusterBuffer(clusterMatrices, clusterMatricesCauterized);
|
data.updateClusterBuffer(clusterMatrices, clusterMatricesCauterized);
|
||||||
|
|
||||||
Transform renderTransform = modelTransform;
|
Transform renderTransform = modelTransform;
|
||||||
|
@ -200,6 +209,11 @@ void CauterizedModel::updateRenderItems() {
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterMatricesCauterized[0]));
|
renderTransform = modelTransform.worldTransform(Transform(clusterMatricesCauterized[0]));
|
||||||
}
|
}
|
||||||
data.updateTransformForCauterizedMesh(renderTransform);
|
data.updateTransformForCauterizedMesh(renderTransform);
|
||||||
|
|
||||||
|
data.setEnableCauterization(enableCauterization);
|
||||||
|
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
|
||||||
|
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||||
|
data.setShapeKey(invalidatePayloadShapeKey, isWireframe);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -760,6 +760,20 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) {
|
||||||
_shapes[shape].drawWire(batch);
|
_shapes[shape].drawWire(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeometryCache::renderShape(gpu::Batch& batch, Shape shape, const glm::vec4& color) {
|
||||||
|
batch.setInputFormat(getSolidStreamFormat());
|
||||||
|
// Color must be set after input format
|
||||||
|
batch._glColor4f(color.r, color.g, color.b, color.a);
|
||||||
|
_shapes[shape].draw(batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color) {
|
||||||
|
batch.setInputFormat(getSolidStreamFormat());
|
||||||
|
// Color must be set after input format
|
||||||
|
batch._glColor4f(color.r, color.g, color.b, color.a);
|
||||||
|
_shapes[shape].drawWire(batch);
|
||||||
|
}
|
||||||
|
|
||||||
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
|
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
|
||||||
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
|
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
|
||||||
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
|
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
|
||||||
|
@ -811,6 +825,14 @@ void GeometryCache::renderWireCube(gpu::Batch& batch) {
|
||||||
renderWireShape(batch, Cube);
|
renderWireShape(batch, Cube);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeometryCache::renderCube(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
|
renderShape(batch, Cube, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometryCache::renderWireCube(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
|
renderWireShape(batch, Cube, color);
|
||||||
|
}
|
||||||
|
|
||||||
void GeometryCache::renderSphere(gpu::Batch& batch) {
|
void GeometryCache::renderSphere(gpu::Batch& batch) {
|
||||||
renderShape(batch, Sphere);
|
renderShape(batch, Sphere);
|
||||||
}
|
}
|
||||||
|
@ -819,6 +841,14 @@ void GeometryCache::renderWireSphere(gpu::Batch& batch) {
|
||||||
renderWireShape(batch, Sphere);
|
renderWireShape(batch, Sphere);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeometryCache::renderSphere(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
|
renderShape(batch, Sphere, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeometryCache::renderWireSphere(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
|
renderWireShape(batch, Sphere, color);
|
||||||
|
}
|
||||||
|
|
||||||
void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
|
void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
|
||||||
int majorRows, int majorCols, float majorEdge,
|
int majorRows, int majorCols, float majorEdge,
|
||||||
int minorRows, int minorCols, float minorEdge,
|
int minorRows, int minorCols, float minorEdge,
|
||||||
|
|
|
@ -251,14 +251,20 @@ public:
|
||||||
// Dynamic geometry
|
// Dynamic geometry
|
||||||
void renderShape(gpu::Batch& batch, Shape shape);
|
void renderShape(gpu::Batch& batch, Shape shape);
|
||||||
void renderWireShape(gpu::Batch& batch, Shape shape);
|
void renderWireShape(gpu::Batch& batch, Shape shape);
|
||||||
|
void renderShape(gpu::Batch& batch, Shape shape, const glm::vec4& color);
|
||||||
|
void renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color);
|
||||||
size_t getShapeTriangleCount(Shape shape);
|
size_t getShapeTriangleCount(Shape shape);
|
||||||
|
|
||||||
void renderCube(gpu::Batch& batch);
|
void renderCube(gpu::Batch& batch);
|
||||||
void renderWireCube(gpu::Batch& batch);
|
void renderWireCube(gpu::Batch& batch);
|
||||||
|
void renderCube(gpu::Batch& batch, const glm::vec4& color);
|
||||||
|
void renderWireCube(gpu::Batch& batch, const glm::vec4& color);
|
||||||
size_t getCubeTriangleCount();
|
size_t getCubeTriangleCount();
|
||||||
|
|
||||||
void renderSphere(gpu::Batch& batch);
|
void renderSphere(gpu::Batch& batch);
|
||||||
void renderWireSphere(gpu::Batch& batch);
|
void renderWireSphere(gpu::Batch& batch);
|
||||||
|
void renderSphere(gpu::Batch& batch, const glm::vec4& color);
|
||||||
|
void renderWireSphere(gpu::Batch& batch, const glm::vec4& color);
|
||||||
size_t getSphereTriangleCount();
|
size_t getSphereTriangleCount();
|
||||||
|
|
||||||
void renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
|
void renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
|
||||||
|
|
|
@ -122,11 +122,6 @@ void MeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||||
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
||||||
|
|
||||||
batch.setInputStream(0, _drawMesh->getVertexStream());
|
batch.setInputStream(0, _drawMesh->getVertexStream());
|
||||||
|
|
||||||
// TODO: Get rid of that extra call
|
|
||||||
if (!_hasColorAttrib) {
|
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, bool enableTextures) const {
|
void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, bool enableTextures) const {
|
||||||
|
@ -325,7 +320,7 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
||||||
_shapeID(shapeIndex) {
|
_shapeID(shapeIndex) {
|
||||||
|
|
||||||
assert(model && model->isLoaded());
|
assert(model && model->isLoaded());
|
||||||
_model = model;
|
_blendedVertexBuffer = model->_blendedVertexBuffers[_meshIndex];
|
||||||
auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex);
|
auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex);
|
||||||
const Model::MeshState& state = model->getMeshState(_meshIndex);
|
const Model::MeshState& state = model->getMeshState(_meshIndex);
|
||||||
|
|
||||||
|
@ -339,13 +334,10 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
||||||
}
|
}
|
||||||
updateTransformForSkinnedMesh(renderTransform, transform);
|
updateTransformForSkinnedMesh(renderTransform, transform);
|
||||||
|
|
||||||
initCache();
|
initCache(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelMeshPartPayload::initCache() {
|
void ModelMeshPartPayload::initCache(const ModelPointer& model) {
|
||||||
ModelPointer model = _model.lock();
|
|
||||||
assert(model && model->isLoaded());
|
|
||||||
|
|
||||||
if (_drawMesh) {
|
if (_drawMesh) {
|
||||||
auto vertexFormat = _drawMesh->getVertexFormat();
|
auto vertexFormat = _drawMesh->getVertexFormat();
|
||||||
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
|
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
|
||||||
|
@ -355,6 +347,7 @@ void ModelMeshPartPayload::initCache() {
|
||||||
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
||||||
|
|
||||||
_isBlendShaped = !mesh.blendshapes.isEmpty();
|
_isBlendShaped = !mesh.blendshapes.isEmpty();
|
||||||
|
_hasTangents = !mesh.tangents.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto networkMaterial = model->getGeometry()->getShapeMaterial(_shapeID);
|
auto networkMaterial = model->getGeometry()->getShapeMaterial(_shapeID);
|
||||||
|
@ -388,94 +381,70 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& render
|
||||||
_worldBound.transform(boundTransform);
|
_worldBound.transform(boundTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemKey ModelMeshPartPayload::getKey() const {
|
void ModelMeshPartPayload::setKey(bool isVisible, bool isLayered) {
|
||||||
ItemKey::Builder builder;
|
ItemKey::Builder builder;
|
||||||
builder.withTypeShape();
|
builder.withTypeShape();
|
||||||
|
|
||||||
ModelPointer model = _model.lock();
|
if (!isVisible) {
|
||||||
if (model) {
|
builder.withInvisible();
|
||||||
if (!model->isVisible()) {
|
}
|
||||||
builder.withInvisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model->isLayeredInFront() || model->isLayeredInHUD()) {
|
if (isLayered) {
|
||||||
builder.withLayered();
|
builder.withLayered();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isBlendShaped || _isSkinned) {
|
if (_isBlendShaped || _isSkinned) {
|
||||||
builder.withDeformed();
|
builder.withDeformed();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_drawMaterial) {
|
if (_drawMaterial) {
|
||||||
auto matKey = _drawMaterial->getKey();
|
auto matKey = _drawMaterial->getKey();
|
||||||
if (matKey.isTranslucent()) {
|
if (matKey.isTranslucent()) {
|
||||||
builder.withTransparent();
|
builder.withTransparent();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
|
||||||
|
_itemKey = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemKey ModelMeshPartPayload::getKey() const {
|
||||||
|
return _itemKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMeshPartPayload::setLayer(bool isLayeredInFront, bool isLayeredInHUD) {
|
||||||
|
if (isLayeredInFront) {
|
||||||
|
_layer = Item::LAYER_3D_FRONT;
|
||||||
|
} else if (isLayeredInHUD) {
|
||||||
|
_layer = Item::LAYER_3D_HUD;
|
||||||
|
} else {
|
||||||
|
_layer = Item::LAYER_3D;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModelMeshPartPayload::getLayer() const {
|
int ModelMeshPartPayload::getLayer() const {
|
||||||
ModelPointer model = _model.lock();
|
return _layer;
|
||||||
if (model) {
|
|
||||||
if (model->isLayeredInFront()) {
|
|
||||||
return Item::LAYER_3D_FRONT;
|
|
||||||
} else if (model->isLayeredInHUD()) {
|
|
||||||
return Item::LAYER_3D_HUD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Item::LAYER_3D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe) {
|
||||||
// guard against partially loaded meshes
|
if (invalidateShapeKey) {
|
||||||
ModelPointer model = _model.lock();
|
_shapeKey = ShapeKey::Builder::invalid();
|
||||||
if (!model || !model->isLoaded() || !model->getGeometry()) {
|
return;
|
||||||
return ShapeKey::Builder::invalid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const FBXGeometry& geometry = model->getFBXGeometry();
|
|
||||||
const auto& networkMeshes = model->getGeometry()->getMeshes();
|
|
||||||
|
|
||||||
// guard against partially loaded meshes
|
|
||||||
if (_meshIndex >= (int)networkMeshes.size() || _meshIndex >= (int)geometry.meshes.size() || _meshIndex >= (int)model->_meshStates.size()) {
|
|
||||||
return ShapeKey::Builder::invalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
|
||||||
|
|
||||||
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
|
||||||
// to false to rebuild out mesh groups.
|
|
||||||
if (_meshIndex < 0 || _meshIndex >= (int)networkMeshes.size() || _meshIndex > geometry.meshes.size()) {
|
|
||||||
model->_needsFixupInScene = true; // trigger remove/add cycle
|
|
||||||
model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
|
||||||
return ShapeKey::Builder::invalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int vertexCount = mesh.vertices.size();
|
|
||||||
if (vertexCount == 0) {
|
|
||||||
// sanity check
|
|
||||||
return ShapeKey::Builder::invalid(); // FIXME
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::MaterialKey drawMaterialKey;
|
model::MaterialKey drawMaterialKey;
|
||||||
if (_drawMaterial) {
|
if (_drawMaterial) {
|
||||||
drawMaterialKey = _drawMaterial->getKey();
|
drawMaterialKey = _drawMaterial->getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
bool hasTangents = drawMaterialKey.isNormalMap() && _hasTangents;
|
||||||
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||||
bool isUnlit = drawMaterialKey.isUnlit();
|
bool isUnlit = drawMaterialKey.isUnlit();
|
||||||
|
|
||||||
bool isSkinned = _isSkinned;
|
bool isSkinned = _isSkinned;
|
||||||
bool wireframe = model->isWireframe();
|
|
||||||
|
|
||||||
if (wireframe) {
|
if (isWireframe) {
|
||||||
isTranslucent = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
isTranslucent = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,10 +469,14 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
if (isSkinned) {
|
if (isSkinned) {
|
||||||
builder.withSkinned();
|
builder.withSkinned();
|
||||||
}
|
}
|
||||||
if (wireframe) {
|
if (isWireframe) {
|
||||||
builder.withWireframe();
|
builder.withWireframe();
|
||||||
}
|
}
|
||||||
return builder.build();
|
_shapeKey = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
|
return _shapeKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||||
|
@ -515,10 +488,9 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||||
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
||||||
|
|
||||||
ModelPointer model = _model.lock();
|
if (_blendedVertexBuffer) {
|
||||||
if (model) {
|
batch.setInputBuffer(0, _blendedVertexBuffer, 0, sizeof(glm::vec3));
|
||||||
batch.setInputBuffer(0, model->_blendedVertexBuffers[_meshIndex], 0, sizeof(glm::vec3));
|
batch.setInputBuffer(1, _blendedVertexBuffer, _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3));
|
||||||
batch.setInputBuffer(1, model->_blendedVertexBuffers[_meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3));
|
|
||||||
batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2));
|
batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2));
|
||||||
} else {
|
} else {
|
||||||
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
|
@ -526,11 +498,6 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||||
batch.setInputStream(0, _drawMesh->getVertexStream());
|
batch.setInputStream(0, _drawMesh->getVertexStream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get rid of that extra call
|
|
||||||
if (!_hasColorAttrib) {
|
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const {
|
void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const {
|
||||||
|
@ -544,31 +511,9 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline:
|
||||||
void ModelMeshPartPayload::render(RenderArgs* args) {
|
void ModelMeshPartPayload::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
||||||
|
|
||||||
ModelPointer model = _model.lock();
|
|
||||||
if (!model || !model->isAddedToScene() || !model->isVisible()) {
|
|
||||||
return; // bail asap
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_state == WAITING_TO_START) {
|
|
||||||
if (model->isLoaded()) {
|
|
||||||
_state = STARTED;
|
|
||||||
model->setRenderItemsNeedUpdate();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_materialNeedsUpdate && model->getGeometry()->areTexturesLoaded()) {
|
|
||||||
model->setRenderItemsNeedUpdate();
|
|
||||||
_materialNeedsUpdate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args) {
|
if (!args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!getShapeKey().isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpu::Batch& batch = *(args->_batch);
|
gpu::Batch& batch = *(args->_batch);
|
||||||
auto locations = args->_shapePipeline->locations;
|
auto locations = args->_shapePipeline->locations;
|
||||||
|
|
|
@ -96,32 +96,32 @@ public:
|
||||||
render::ShapeKey getShapeKey() const override; // shape interface
|
render::ShapeKey getShapeKey() const override; // shape interface
|
||||||
void render(RenderArgs* args) override;
|
void render(RenderArgs* args) override;
|
||||||
|
|
||||||
|
void setKey(bool isVisible, bool isLayered);
|
||||||
|
void setLayer(bool isLayeredInFront, bool isLayeredInHUD);
|
||||||
|
void setShapeKey(bool invalidateShapeKey, bool isWireframe);
|
||||||
|
|
||||||
// ModelMeshPartPayload functions to perform render
|
// ModelMeshPartPayload functions to perform render
|
||||||
void bindMesh(gpu::Batch& batch) override;
|
void bindMesh(gpu::Batch& batch) override;
|
||||||
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
||||||
|
|
||||||
void initCache();
|
|
||||||
|
|
||||||
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
|
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
|
||||||
|
|
||||||
gpu::BufferPointer _clusterBuffer;
|
gpu::BufferPointer _clusterBuffer;
|
||||||
ModelWeakPointer _model;
|
|
||||||
|
|
||||||
int _meshIndex;
|
int _meshIndex;
|
||||||
int _shapeID;
|
int _shapeID;
|
||||||
|
|
||||||
bool _isSkinned{ false };
|
bool _isSkinned{ false };
|
||||||
bool _isBlendShaped { false };
|
bool _isBlendShaped { false };
|
||||||
bool _materialNeedsUpdate { true };
|
bool _hasTangents { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initCache(const ModelPointer& model);
|
||||||
|
|
||||||
enum State : uint8_t {
|
gpu::BufferPointer _blendedVertexBuffer;
|
||||||
WAITING_TO_START = 0,
|
render::ItemKey _itemKey { render::ItemKey::Builder::opaqueShape().build() };
|
||||||
STARTED = 1,
|
render::ShapeKey _shapeKey { render::ShapeKey::Builder::invalid() };
|
||||||
};
|
int _layer { render::Item::LAYER_3D };
|
||||||
|
|
||||||
mutable State _state { WAITING_TO_START } ;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
|
@ -210,6 +210,24 @@ int Model::getRenderInfoTextureCount() {
|
||||||
return _renderInfoTextureCount;
|
return _renderInfoTextureCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Model::shouldInvalidatePayloadShapeKey(int meshIndex) {
|
||||||
|
if (!getGeometry()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FBXGeometry& geometry = getFBXGeometry();
|
||||||
|
const auto& networkMeshes = getGeometry()->getMeshes();
|
||||||
|
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
||||||
|
// to false to rebuild out mesh groups.
|
||||||
|
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)_meshStates.size()) {
|
||||||
|
_needsFixupInScene = true; // trigger remove/add cycle
|
||||||
|
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Model::updateRenderItems() {
|
void Model::updateRenderItems() {
|
||||||
if (!_addedToScene) {
|
if (!_addedToScene) {
|
||||||
return;
|
return;
|
||||||
|
@ -237,6 +255,11 @@ void Model::updateRenderItems() {
|
||||||
Transform modelTransform = self->getTransform();
|
Transform modelTransform = self->getTransform();
|
||||||
modelTransform.setScale(glm::vec3(1.0f));
|
modelTransform.setScale(glm::vec3(1.0f));
|
||||||
|
|
||||||
|
bool isWireframe = self->isWireframe();
|
||||||
|
bool isVisible = self->isVisible();
|
||||||
|
bool isLayeredInFront = self->isLayeredInFront();
|
||||||
|
bool isLayeredInHUD = self->isLayeredInHUD();
|
||||||
|
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) {
|
for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) {
|
||||||
|
|
||||||
|
@ -244,13 +267,20 @@ void Model::updateRenderItems() {
|
||||||
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||||
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
||||||
|
|
||||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, clusterMatrices](ModelMeshPartPayload& data) {
|
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
|
|
||||||
|
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, clusterMatrices, invalidatePayloadShapeKey,
|
||||||
|
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
|
||||||
data.updateClusterBuffer(clusterMatrices);
|
data.updateClusterBuffer(clusterMatrices);
|
||||||
Transform renderTransform = modelTransform;
|
Transform renderTransform = modelTransform;
|
||||||
if (clusterMatrices.size() == 1) {
|
if (clusterMatrices.size() == 1) {
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0]));
|
renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0]));
|
||||||
}
|
}
|
||||||
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
||||||
|
|
||||||
|
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
|
||||||
|
data.setLayer(isLayeredInFront, isLayeredInHUD);
|
||||||
|
data.setShapeKey(invalidatePayloadShapeKey, isWireframe);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,16 +302,6 @@ void Model::setRenderItemsNeedUpdate() {
|
||||||
emit requestRenderUpdate();
|
emit requestRenderUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::initJointTransforms() {
|
|
||||||
if (isLoaded()) {
|
|
||||||
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
|
|
||||||
_rig.setModelOffset(modelOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Model::init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Model::reset() {
|
void Model::reset() {
|
||||||
if (isLoaded()) {
|
if (isLoaded()) {
|
||||||
const FBXGeometry& geometry = getFBXGeometry();
|
const FBXGeometry& geometry = getFBXGeometry();
|
||||||
|
|
|
@ -122,7 +122,6 @@ public:
|
||||||
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
||||||
bool isWireframe() const { return _isWireframe; }
|
bool isWireframe() const { return _isWireframe; }
|
||||||
|
|
||||||
void init();
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint);
|
void setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint);
|
||||||
|
@ -346,11 +345,7 @@ protected:
|
||||||
// hook for derived classes to be notified when setUrl invalidates the current model.
|
// hook for derived classes to be notified when setUrl invalidates the current model.
|
||||||
virtual void onInvalidate() {};
|
virtual void onInvalidate() {};
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void deleteGeometry();
|
virtual void deleteGeometry();
|
||||||
void initJointTransforms();
|
|
||||||
|
|
||||||
QVector<float> _blendshapeCoefficients;
|
QVector<float> _blendshapeCoefficients;
|
||||||
|
|
||||||
|
@ -419,6 +414,8 @@ protected:
|
||||||
bool _isLayeredInFront { false };
|
bool _isLayeredInFront { false };
|
||||||
bool _isLayeredInHUD { false };
|
bool _isLayeredInHUD { false };
|
||||||
|
|
||||||
|
bool shouldInvalidatePayloadShapeKey(int meshIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _loadingPriority { 0.0f };
|
float _loadingPriority { 0.0f };
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
glm::vec3 getPosition() const override { return _thing->getPosition(); }
|
glm::vec3 getPosition() const override { return _thing->getPosition(); }
|
||||||
float getRadius() const override { return 0.5f * _thing->getBoundingRadius(); }
|
float getRadius() const override { return 0.5f * _thing->getBoundingRadius(); }
|
||||||
uint64_t getTimestamp() const override { return _thing->getLastTime(); }
|
uint64_t getTimestamp() const override { return _thing->getLastTime(); }
|
||||||
const Thing& getThing() const { return _thing; }
|
Thing getThing() const { return _thing; }
|
||||||
private:
|
private:
|
||||||
Thing _thing;
|
Thing _thing;
|
||||||
};
|
};
|
||||||
|
@ -43,6 +43,13 @@
|
||||||
|
|
||||||
(3) Loop over your priority queue and do timeboxed work:
|
(3) Loop over your priority queue and do timeboxed work:
|
||||||
|
|
||||||
|
NOTE: Be careful using references to members of instances of T from std::priority_queue<T>.
|
||||||
|
Under the hood std::priority_queue<T> may re-use instances of T.
|
||||||
|
For example, after a pop() or a push() the top T may have the same memory address
|
||||||
|
as the top T before the pop() or push() (but point to a swapped instance of T).
|
||||||
|
This causes a reference to member variable of T to point to a different value
|
||||||
|
when operations taken on std::priority_queue<T> shuffle around the instances of T.
|
||||||
|
|
||||||
uint64_t cutoffTime = usecTimestampNow() + TIME_BUDGET;
|
uint64_t cutoffTime = usecTimestampNow() + TIME_BUDGET;
|
||||||
while (!sortedThings.empty()) {
|
while (!sortedThings.empty()) {
|
||||||
const Thing& thing = sortedThings.top();
|
const Thing& thing = sortedThings.top();
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "SharedLogging.h"
|
#include "SharedLogging.h"
|
||||||
|
|
||||||
const float defaultAACubeSize = 1.0f;
|
const float defaultAACubeSize = 1.0f;
|
||||||
const int maxParentingChain = 30;
|
const int MAX_PARENTING_CHAIN_SIZE = 30;
|
||||||
|
|
||||||
SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
|
SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
|
||||||
_nestableType(nestableType),
|
_nestableType(nestableType),
|
||||||
|
@ -28,6 +28,7 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
|
||||||
// set flags in _transform
|
// set flags in _transform
|
||||||
_transform.setTranslation(glm::vec3(0.0f));
|
_transform.setTranslation(glm::vec3(0.0f));
|
||||||
_transform.setRotation(glm::quat());
|
_transform.setRotation(glm::quat());
|
||||||
|
_transform.setScale(1.0f);
|
||||||
_scaleChanged = usecTimestampNow();
|
_scaleChanged = usecTimestampNow();
|
||||||
_translationChanged = usecTimestampNow();
|
_translationChanged = usecTimestampNow();
|
||||||
_rotationChanged = usecTimestampNow();
|
_rotationChanged = usecTimestampNow();
|
||||||
|
@ -85,6 +86,9 @@ Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const
|
||||||
}
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
result = parent->getTransform(_parentJointIndex, success, depth + 1);
|
result = parent->getTransform(_parentJointIndex, success, depth + 1);
|
||||||
|
if (getScalesWithParent()) {
|
||||||
|
result.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +169,7 @@ void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) {
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
|
glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
|
||||||
const QUuid& parentID, int parentJointIndex,
|
const QUuid& parentID, int parentJointIndex,
|
||||||
bool& success) {
|
bool scalesWithParent, bool& success) {
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
if (!parentFinder) {
|
if (!parentFinder) {
|
||||||
success = false;
|
success = false;
|
||||||
|
@ -189,6 +193,9 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return glm::vec3(0.0f);
|
return glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
|
@ -199,7 +206,7 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
|
||||||
|
|
||||||
glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
|
glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
|
||||||
const QUuid& parentID, int parentJointIndex,
|
const QUuid& parentID, int parentJointIndex,
|
||||||
bool& success) {
|
bool scalesWithParent, bool& success) {
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
if (!parentFinder) {
|
if (!parentFinder) {
|
||||||
success = false;
|
success = false;
|
||||||
|
@ -223,6 +230,9 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return glm::quat();
|
return glm::quat();
|
||||||
}
|
}
|
||||||
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
|
@ -231,7 +241,7 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
|
glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
|
||||||
int parentJointIndex, bool& success) {
|
int parentJointIndex, bool scalesWithParent, bool& success) {
|
||||||
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
||||||
if (!success || !parent) {
|
if (!success || !parent) {
|
||||||
return velocity;
|
return velocity;
|
||||||
|
@ -240,6 +250,9 @@ glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, con
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
glm::vec3 parentVelocity = parent->getWorldVelocity(success);
|
glm::vec3 parentVelocity = parent->getWorldVelocity(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return velocity;
|
return velocity;
|
||||||
|
@ -249,7 +262,7 @@ glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, con
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
|
glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
|
||||||
int parentJointIndex, bool& success) {
|
int parentJointIndex, bool scalesWithParent, bool& success) {
|
||||||
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
||||||
if (!success || !parent) {
|
if (!success || !parent) {
|
||||||
return angularVelocity;
|
return angularVelocity;
|
||||||
|
@ -258,12 +271,50 @@ glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angula
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return angularVelocity;
|
return angularVelocity;
|
||||||
}
|
}
|
||||||
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
|
|
||||||
return glm::inverse(parentTransform.getRotation()) * angularVelocity;
|
return glm::inverse(parentTransform.getRotation()) * angularVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glm::vec3 SpatiallyNestable::worldToLocalDimensions(const glm::vec3& dimensions,
|
||||||
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool scalesWithParent, bool& success) {
|
||||||
|
if (!scalesWithParent) {
|
||||||
|
success = true;
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
if (!parentFinder) {
|
||||||
|
success = false;
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform parentTransform;
|
||||||
|
auto parentWP = parentFinder->find(parentID, success);
|
||||||
|
if (!success) {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parent = parentWP.lock();
|
||||||
|
if (!parentID.isNull() && !parent) {
|
||||||
|
success = false;
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
if (parent) {
|
||||||
|
return dimensions / parent->scaleForChildren();
|
||||||
|
}
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
|
glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
|
||||||
const QUuid& parentID, int parentJointIndex,
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool scalesWithParent,
|
||||||
bool& success) {
|
bool& success) {
|
||||||
Transform result;
|
Transform result;
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
@ -289,6 +340,9 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return glm::vec3(0.0f);
|
return glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
|
@ -300,6 +354,7 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
|
||||||
|
|
||||||
glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
|
glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
|
||||||
const QUuid& parentID, int parentJointIndex,
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool scalesWithParent,
|
||||||
bool& success) {
|
bool& success) {
|
||||||
Transform result;
|
Transform result;
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
@ -325,7 +380,9 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return glm::quat();
|
return glm::quat();
|
||||||
}
|
}
|
||||||
parentTransform.setScale(1.0f);
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
|
@ -336,7 +393,7 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, const QUuid& parentID,
|
glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, const QUuid& parentID,
|
||||||
int parentJointIndex, bool& success) {
|
int parentJointIndex, bool scalesWithParent, bool& success) {
|
||||||
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
||||||
if (!success || !parent) {
|
if (!success || !parent) {
|
||||||
return velocity;
|
return velocity;
|
||||||
|
@ -345,6 +402,9 @@ glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, con
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
glm::vec3 parentVelocity = parent->getWorldVelocity(success);
|
glm::vec3 parentVelocity = parent->getWorldVelocity(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return velocity;
|
return velocity;
|
||||||
|
@ -354,7 +414,7 @@ glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, con
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
|
glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
|
||||||
int parentJointIndex, bool& success) {
|
int parentJointIndex, bool scalesWithParent, bool& success) {
|
||||||
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
|
||||||
if (!success || !parent) {
|
if (!success || !parent) {
|
||||||
return angularVelocity;
|
return angularVelocity;
|
||||||
|
@ -363,10 +423,47 @@ glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angula
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return angularVelocity;
|
return angularVelocity;
|
||||||
}
|
}
|
||||||
|
if (scalesWithParent) {
|
||||||
|
parentTransform.setScale(parent->scaleForChildren());
|
||||||
|
}
|
||||||
return parentTransform.getRotation() * angularVelocity;
|
return parentTransform.getRotation() * angularVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glm::vec3 SpatiallyNestable::localToWorldDimensions(const glm::vec3& dimensions,
|
||||||
|
const QUuid& parentID, int parentJointIndex, bool scalesWithParent,
|
||||||
|
bool& success) {
|
||||||
|
if (!scalesWithParent) {
|
||||||
|
success = true;
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform result;
|
||||||
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
if (!parentFinder) {
|
||||||
|
success = false;
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform parentTransform;
|
||||||
|
auto parentWP = parentFinder->find(parentID, success);
|
||||||
|
if (!success) {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parent = parentWP.lock();
|
||||||
|
if (!parentID.isNull() && !parent) {
|
||||||
|
success = false;
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
if (parent) {
|
||||||
|
return dimensions * parent->scaleForChildren();
|
||||||
|
}
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getWorldPosition(bool& success) const {
|
glm::vec3 SpatiallyNestable::getWorldPosition(bool& success) const {
|
||||||
return getTransform(success).getTranslation();
|
return getTransform(success).getTranslation();
|
||||||
}
|
}
|
||||||
|
@ -615,10 +712,10 @@ const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, i
|
||||||
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
||||||
Transform jointInWorldFrame;
|
Transform jointInWorldFrame;
|
||||||
|
|
||||||
if (depth > maxParentingChain) {
|
if (depth > MAX_PARENTING_CHAIN_SIZE) {
|
||||||
success = false;
|
success = false;
|
||||||
// someone created a loop. break it...
|
// someone created a loop. break it...
|
||||||
qCDebug(shared) << "Parenting loop detected.";
|
qCDebug(shared) << "Parenting loop detected: " << getID();
|
||||||
SpatiallyNestablePointer _this = getThisPointer();
|
SpatiallyNestablePointer _this = getThisPointer();
|
||||||
_this->setParentID(QUuid());
|
_this->setParentID(QUuid());
|
||||||
bool setPositionSuccess;
|
bool setPositionSuccess;
|
||||||
|
|
|
@ -50,19 +50,28 @@ public:
|
||||||
virtual quint16 getParentJointIndex() const { return _parentJointIndex; }
|
virtual quint16 getParentJointIndex() const { return _parentJointIndex; }
|
||||||
virtual void setParentJointIndex(quint16 parentJointIndex);
|
virtual void setParentJointIndex(quint16 parentJointIndex);
|
||||||
|
|
||||||
static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success);
|
static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex,
|
||||||
static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success);
|
bool scalesWithParent, bool& success);
|
||||||
|
static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool scalesWithParent, bool& success);
|
||||||
static glm::vec3 worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
|
static glm::vec3 worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
|
||||||
int parentJointIndex, bool& success);
|
int parentJointIndex, bool scalesWithParent, bool& success);
|
||||||
static glm::vec3 worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
|
static glm::vec3 worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
|
||||||
int parentJointIndex, bool& success);
|
int parentJointIndex, bool scalesWithParent, bool& success);
|
||||||
|
static glm::vec3 worldToLocalDimensions(const glm::vec3& dimensions, const QUuid& parentID,
|
||||||
|
int parentJointIndex, bool scalesWithParent, bool& success);
|
||||||
|
|
||||||
static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success);
|
static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex,
|
||||||
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success);
|
bool scalesWithParent, bool& success);
|
||||||
|
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool scalesWithParent, bool& success);
|
||||||
static glm::vec3 localToWorldVelocity(const glm::vec3& velocity,
|
static glm::vec3 localToWorldVelocity(const glm::vec3& velocity,
|
||||||
const QUuid& parentID, int parentJointIndex, bool& success);
|
const QUuid& parentID, int parentJointIndex, bool scalesWithParent, bool& success);
|
||||||
static glm::vec3 localToWorldAngularVelocity(const glm::vec3& angularVelocity,
|
static glm::vec3 localToWorldAngularVelocity(const glm::vec3& angularVelocity,
|
||||||
const QUuid& parentID, int parentJointIndex, bool& success);
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool scalesWithParent, bool& success);
|
||||||
|
static glm::vec3 localToWorldDimensions(const glm::vec3& dimensions, const QUuid& parentID,
|
||||||
|
int parentJointIndex, bool scalesWithParent, bool& success);
|
||||||
|
|
||||||
static QString nestableTypeToString(NestableType nestableType);
|
static QString nestableTypeToString(NestableType nestableType);
|
||||||
|
|
||||||
|
@ -140,6 +149,9 @@ public:
|
||||||
virtual glm::vec3 getLocalSNScale() const;
|
virtual glm::vec3 getLocalSNScale() const;
|
||||||
virtual void setLocalSNScale(const glm::vec3& scale);
|
virtual void setLocalSNScale(const glm::vec3& scale);
|
||||||
|
|
||||||
|
virtual bool getScalesWithParent() const { return false; }
|
||||||
|
virtual glm::vec3 scaleForChildren() const { return glm::vec3(1.0f); }
|
||||||
|
|
||||||
QList<SpatiallyNestablePointer> getChildren() const;
|
QList<SpatiallyNestablePointer> getChildren() const;
|
||||||
bool hasChildren() const;
|
bool hasChildren() const;
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,8 @@
|
||||||
itemName: name,
|
itemName: name,
|
||||||
itemPrice: price ? parseInt(price, 10) : 0,
|
itemPrice: price ? parseInt(price, 10) : 0,
|
||||||
itemHref: href,
|
itemHref: href,
|
||||||
referrer: referrer
|
referrer: referrer,
|
||||||
|
itemAuthor: author
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
/* global Tablet, Script, HMD, UserActivityLogger, Entities */
|
/* global Tablet, Script, HMD, UserActivityLogger, Entities, Account, Wallet, ContextOverlay, Settings, Camera, Vec3,
|
||||||
|
Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow */
|
||||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||||
|
|
||||||
var selectionDisplay = null; // for gridTool.js to ignore
|
var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
|
@ -219,6 +220,41 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
|
|
||||||
function rezEntity(itemHref, isWearable) {
|
function rezEntity(itemHref, isWearable) {
|
||||||
var success = Clipboard.importEntities(itemHref);
|
var success = Clipboard.importEntities(itemHref);
|
||||||
|
var wearableLocalPosition = null;
|
||||||
|
var wearableLocalRotation = null;
|
||||||
|
var wearableLocalDimensions = null;
|
||||||
|
var wearableDimensions = null;
|
||||||
|
|
||||||
|
if (isWearable) {
|
||||||
|
var wearableTransforms = Settings.getValue("io.highfidelity.avatarStore.checkOut.transforms");
|
||||||
|
if (!wearableTransforms) {
|
||||||
|
// TODO delete this clause
|
||||||
|
wearableTransforms = Settings.getValue("io.highfidelity.avatarStore.checkOut.tranforms");
|
||||||
|
}
|
||||||
|
var certPos = itemHref.search("certificate_id="); // TODO how do I parse a URL from here?
|
||||||
|
if (certPos >= 0) {
|
||||||
|
certPos += 15; // length of "certificate_id="
|
||||||
|
var certURLEncoded = itemHref.substring(certPos);
|
||||||
|
var certB64Encoded = decodeURIComponent(certURLEncoded);
|
||||||
|
for (var key in wearableTransforms) {
|
||||||
|
if (wearableTransforms.hasOwnProperty(key)) {
|
||||||
|
var certificateTransforms = wearableTransforms[key].certificateTransforms;
|
||||||
|
if (certificateTransforms) {
|
||||||
|
for (var certID in certificateTransforms) {
|
||||||
|
if (certificateTransforms.hasOwnProperty(certID) &&
|
||||||
|
certID == certB64Encoded) {
|
||||||
|
var certificateTransform = certificateTransforms[certID];
|
||||||
|
wearableLocalPosition = certificateTransform.localPosition;
|
||||||
|
wearableLocalRotation = certificateTransform.localRotation;
|
||||||
|
wearableLocalDimensions = certificateTransform.localDimensions;
|
||||||
|
wearableDimensions = certificateTransform.dimensions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
var VERY_LARGE = 10000;
|
var VERY_LARGE = 10000;
|
||||||
|
@ -287,6 +323,24 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isWearable) {
|
||||||
|
// apply the relative offsets saved during checkout
|
||||||
|
var offsets = {};
|
||||||
|
if (wearableLocalPosition) {
|
||||||
|
offsets.localPosition = wearableLocalPosition;
|
||||||
|
}
|
||||||
|
if (wearableLocalRotation) {
|
||||||
|
offsets.localRotation = wearableLocalRotation;
|
||||||
|
}
|
||||||
|
if (wearableLocalDimensions) {
|
||||||
|
offsets.localDimensions = wearableLocalDimensions;
|
||||||
|
} else if (wearableDimensions) {
|
||||||
|
offsets.dimensions = wearableDimensions;
|
||||||
|
}
|
||||||
|
// we currently assume a wearable is a single entity
|
||||||
|
Entities.editEntity(pastedEntityIDs[0], offsets);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Window.notifyEditError("Can't import entities: entities would be out of bounds.");
|
Window.notifyEditError("Can't import entities: entities would be out of bounds.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,19 +29,18 @@ void TestShapes::renderTest(size_t testId, RenderArgs* args) {
|
||||||
float seconds = secTimestampNow() - startSecs;
|
float seconds = secTimestampNow() - startSecs;
|
||||||
seconds /= 4.0f;
|
seconds /= 4.0f;
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
batch._glColor4f(0.8f, 0.25f, 0.25f, 1.0f);
|
const auto color = glm::vec4(0.8f, 0.25f, 0.25f, 1.0f);
|
||||||
|
|
||||||
bool wire = (seconds - floorf(seconds) > 0.5f);
|
bool wire = (seconds - floorf(seconds) > 0.5f);
|
||||||
int shapeIndex = ((int)seconds) % TYPE_COUNT;
|
int shapeIndex = ((int)seconds) % TYPE_COUNT;
|
||||||
if (wire) {
|
if (wire) {
|
||||||
geometryCache->renderWireShape(batch, SHAPE[shapeIndex]);
|
geometryCache->renderWireShape(batch, SHAPE[shapeIndex], color);
|
||||||
} else {
|
} else {
|
||||||
geometryCache->renderShape(batch, SHAPE[shapeIndex]);
|
geometryCache->renderShape(batch, SHAPE[shapeIndex], color);
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.setModelTransform(Transform().setScale(1.01f));
|
batch.setModelTransform(Transform().setScale(1.01f));
|
||||||
batch._glColor4f(1, 1, 1, 1);
|
geometryCache->renderWireCube(batch, glm::vec4(1,1,1,1));
|
||||||
geometryCache->renderWireCube(batch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue