mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-19 14:03:20 +02:00
Merge pull request #11462 from highfidelity/game-render-interface
Moving transform evaluation out from render loop to gameplay loop / fixing tablet tearing
This commit is contained in:
commit
9317ad38aa
32 changed files with 197 additions and 132 deletions
|
@ -268,18 +268,17 @@ void Base3DOverlay::update(float duration) {
|
|||
|
||||
// In Base3DOverlay, if its location or bound changed, the renderTrasnformDirty flag is true.
|
||||
// then the correct transform used for rendering is computed in the update transaction and assigned.
|
||||
// TODO: Fix the value to be computed in main thread now and passed by value to the render item.
|
||||
// This is the simplest fix for the web overlay of the tablet for now
|
||||
if (_renderTransformDirty) {
|
||||
_renderTransformDirty = false;
|
||||
auto itemID = getRenderItemID();
|
||||
if (render::Item::isValidID(itemID)) {
|
||||
_renderTransformDirty = false;
|
||||
// Capture the render transform value in game loop before
|
||||
auto latestTransform = evalRenderTransform();
|
||||
render::ScenePointer scene = qApp->getMain3DScene();
|
||||
render::Transaction transaction;
|
||||
transaction.updateItem<Overlay>(itemID, [](Overlay& data) {
|
||||
transaction.updateItem<Overlay>(itemID, [latestTransform](Overlay& data) {
|
||||
auto overlay3D = dynamic_cast<Base3DOverlay*>(&data);
|
||||
if (overlay3D) {
|
||||
auto latestTransform = overlay3D->evalRenderTransform();
|
||||
overlay3D->setRenderTransform(latestTransform);
|
||||
}
|
||||
});
|
||||
|
@ -292,7 +291,7 @@ void Base3DOverlay::notifyRenderTransformChange() const {
|
|||
_renderTransformDirty = true;
|
||||
}
|
||||
|
||||
Transform Base3DOverlay::evalRenderTransform() const {
|
||||
Transform Base3DOverlay::evalRenderTransform() {
|
||||
return getTransform();
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ protected:
|
|||
virtual void parentDeleted() override;
|
||||
|
||||
mutable Transform _renderTransform;
|
||||
virtual Transform evalRenderTransform() const;
|
||||
virtual Transform evalRenderTransform();
|
||||
virtual void setRenderTransform(const Transform& transform);
|
||||
const Transform& getRenderTransform() const { return _renderTransform; }
|
||||
|
||||
|
|
|
@ -45,3 +45,14 @@ bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) {
|
|||
}
|
||||
return transformChanged;
|
||||
}
|
||||
|
||||
Transform Billboard3DOverlay::evalRenderTransform() {
|
||||
Transform transform = getTransform();
|
||||
bool transformChanged = applyTransformTo(transform, true);
|
||||
// If the transform is not modified, setting the transform to
|
||||
// itself will cause drift over time due to floating point errors.
|
||||
if (transformChanged) {
|
||||
setTransform(transform);
|
||||
}
|
||||
return transform;
|
||||
}
|
|
@ -28,6 +28,8 @@ public:
|
|||
|
||||
protected:
|
||||
virtual bool applyTransformTo(Transform& transform, bool force = false) override;
|
||||
|
||||
Transform evalRenderTransform() override;
|
||||
};
|
||||
|
||||
#endif // hifi_Billboard3DOverlay_h
|
||||
|
|
|
@ -84,12 +84,7 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
batch.setPipeline(args->_shapePipeline->pipeline);
|
||||
}
|
||||
|
||||
// FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform()
|
||||
|
||||
auto transform = getTransform();
|
||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||
batch.setModelTransform(transform);
|
||||
batch.setModelTransform(getRenderTransform());
|
||||
|
||||
// for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
|
||||
// we just draw a line...
|
||||
|
|
|
@ -53,18 +53,11 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
const float MAX_COLOR = 255.0f;
|
||||
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
|
||||
// TODO: handle registration point??
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform()
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
|
||||
auto batch = args->_batch;
|
||||
|
||||
if (batch) {
|
||||
Transform transform;
|
||||
transform.setTranslation(position);
|
||||
transform.setRotation(rotation);
|
||||
Transform transform = getRenderTransform();
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto shapePipeline = args->_shapePipeline;
|
||||
if (!shapePipeline) {
|
||||
|
@ -72,12 +65,12 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
if (_isSolid) {
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderSolidCubeInstance(args, *batch, cubeColor, shapePipeline);
|
||||
} else {
|
||||
geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
|
||||
if (getIsDashedLine()) {
|
||||
auto dimensions = transform.getScale();
|
||||
transform.setScale(1.0f);
|
||||
batch->setModelTransform(transform);
|
||||
|
||||
|
@ -108,7 +101,6 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor, _geometryIds[11]);
|
||||
|
||||
} else {
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
geometryCache->renderWireCubeInstance(args, *batch, cubeColor, shapePipeline);
|
||||
}
|
||||
|
@ -149,3 +141,16 @@ QVariant Cube3DOverlay::getProperty(const QString& property) {
|
|||
|
||||
return Volume3DOverlay::getProperty(property);
|
||||
}
|
||||
|
||||
Transform Cube3DOverlay::evalRenderTransform() {
|
||||
// TODO: handle registration point??
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
Transform transform;
|
||||
transform.setScale(dimensions);
|
||||
transform.setTranslation(position);
|
||||
transform.setRotation(rotation);
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ public:
|
|||
void setProperties(const QVariantMap& properties) override;
|
||||
QVariant getProperty(const QString& property) override;
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
float _borderSize;
|
||||
// edges on a cube
|
||||
|
|
|
@ -79,10 +79,7 @@ void Grid3DOverlay::render(RenderArgs* args) {
|
|||
position += glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z);
|
||||
}
|
||||
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform()
|
||||
Transform transform;
|
||||
transform.setRotation(getRotation());
|
||||
transform.setScale(glm::vec3(getDimensions(), 1.0f));
|
||||
Transform transform = getRenderTransform();
|
||||
transform.setTranslation(position);
|
||||
batch->setModelTransform(transform);
|
||||
const float MINOR_GRID_EDGE = 0.0025f;
|
||||
|
@ -146,3 +143,10 @@ void Grid3DOverlay::updateGrid() {
|
|||
_minorGridRowDivisions = getDimensions().x / _minorGridEvery;
|
||||
_minorGridColDivisions = getDimensions().y / _minorGridEvery;
|
||||
}
|
||||
|
||||
Transform Grid3DOverlay::evalRenderTransform() {
|
||||
Transform transform;
|
||||
transform.setRotation(getRotation());
|
||||
transform.setScale(glm::vec3(getDimensions(), 1.0f));
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ public:
|
|||
// Grids are UI tools, and may not be intersected (pickable)
|
||||
virtual bool findRayIntersection(const glm::vec3&, const glm::vec3&, float&, BoxFace&, glm::vec3&) override { return false; }
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
void updateGrid();
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ void Image3DOverlay::update(float deltatime) {
|
|||
setTransform(transform);
|
||||
}
|
||||
#endif
|
||||
Parent::update(deltatime);
|
||||
}
|
||||
|
||||
void Image3DOverlay::render(RenderArgs* args) {
|
||||
|
@ -116,18 +117,8 @@ void Image3DOverlay::render(RenderArgs* args) {
|
|||
const float MAX_COLOR = 255.0f;
|
||||
xColor color = getColor();
|
||||
float alpha = getAlpha();
|
||||
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform()
|
||||
Transform transform = getTransform();
|
||||
bool transformChanged = applyTransformTo(transform, true);
|
||||
// If the transform is not modified, setting the transform to
|
||||
// itself will cause drift over time due to floating point errors.
|
||||
if (transformChanged) {
|
||||
setTransform(transform);
|
||||
}
|
||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||
|
||||
batch->setModelTransform(transform);
|
||||
batch->setModelTransform(getRenderTransform());
|
||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||
|
@ -249,3 +240,9 @@ bool Image3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec
|
|||
Image3DOverlay* Image3DOverlay::createClone() const {
|
||||
return new Image3DOverlay(this);
|
||||
}
|
||||
|
||||
Transform Image3DOverlay::evalRenderTransform() {
|
||||
auto transform = Parent::evalRenderTransform();
|
||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
class Image3DOverlay : public Billboard3DOverlay {
|
||||
Q_OBJECT
|
||||
using Parent = Billboard3DOverlay;
|
||||
|
||||
public:
|
||||
static QString const TYPE;
|
||||
|
@ -46,6 +47,9 @@ public:
|
|||
|
||||
virtual Image3DOverlay* createClone() const override;
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
QString _url;
|
||||
NetworkTexturePointer _texture;
|
||||
|
|
|
@ -132,10 +132,10 @@ void Line3DOverlay::render(RenderArgs* args) {
|
|||
glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
auto batch = args->_batch;
|
||||
if (batch) {
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform and start and end from here, do the custom things needed in evalRenderTransform()
|
||||
batch->setModelTransform(Transform());
|
||||
glm::vec3 start = getStart();
|
||||
glm::vec3 end = getEnd();
|
||||
auto& renderTransform = getRenderTransform();
|
||||
glm::vec3 start = renderTransform.getTranslation();
|
||||
glm::vec3 end = renderTransform.transform(vec3(0.0, 0.0, -1.0));
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
if (getIsDashedLine()) {
|
||||
|
@ -268,3 +268,21 @@ QVariant Line3DOverlay::getProperty(const QString& property) {
|
|||
Line3DOverlay* Line3DOverlay::createClone() const {
|
||||
return new Line3DOverlay(this);
|
||||
}
|
||||
|
||||
Transform Line3DOverlay::evalRenderTransform() {
|
||||
// Capture start and endin the renderTransform:
|
||||
// start is the origin
|
||||
// end is at the tip of the front axis aka -Z
|
||||
Transform transform;
|
||||
transform.setTranslation( getStart());
|
||||
auto endPos = getEnd();
|
||||
|
||||
auto vec = endPos - transform.getTranslation();
|
||||
auto scale = glm::length(vec);
|
||||
auto dir = vec / scale;
|
||||
auto orientation = glm::rotation(glm::vec3(0,0,-1), dir);
|
||||
transform.setRotation(orientation);
|
||||
transform.setScale(scale);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
class Line3DOverlay : public Base3DOverlay {
|
||||
Q_OBJECT
|
||||
using Parent = Base3DOverlay;
|
||||
|
||||
public:
|
||||
static QString const TYPE;
|
||||
|
@ -56,6 +57,9 @@ public:
|
|||
QUuid getEndParentID() const { return _endParentID; }
|
||||
quint16 getEndJointIndex() const { return _endParentJointIndex; }
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
QUuid _endParentID;
|
||||
quint16 _endParentJointIndex { INVALID_JOINT_INDEX };
|
||||
|
|
|
@ -46,8 +46,7 @@ void ModelOverlay::update(float deltatime) {
|
|||
if (_updateModel) {
|
||||
_updateModel = false;
|
||||
_model->setSnapModelToCenter(true);
|
||||
Transform transform = getTransform();
|
||||
transform.setScale(1.0f); // disable inherited scale
|
||||
Transform transform = evalRenderTransform();
|
||||
if (_scaleToFit) {
|
||||
_model->setScaleToFit(true, transform.getScale() * getDimensions());
|
||||
} else {
|
||||
|
@ -280,6 +279,12 @@ ModelOverlay* ModelOverlay::createClone() const {
|
|||
return new ModelOverlay(this);
|
||||
}
|
||||
|
||||
Transform ModelOverlay::evalRenderTransform() {
|
||||
Transform transform = getTransform();
|
||||
transform.setScale(1.0f); // disable inherited scale
|
||||
return transform;
|
||||
}
|
||||
|
||||
void ModelOverlay::locationChanged(bool tellPhysics) {
|
||||
Base3DOverlay::locationChanged(tellPhysics);
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
float getLoadPriority() const { return _loadPriority; }
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
// helper to extract metadata from our Model's rigged joints
|
||||
template <typename itemType> using mapFunction = std::function<itemType(int jointIndex)>;
|
||||
template <typename vectorType, typename itemType>
|
||||
|
|
|
@ -35,6 +35,11 @@ AABox Planar3DOverlay::getBounds() const {
|
|||
return AABox(extents);
|
||||
}
|
||||
|
||||
void Planar3DOverlay::setDimensions(const glm::vec2& value) {
|
||||
_dimensions = value;
|
||||
notifyRenderTransformChange();
|
||||
}
|
||||
|
||||
void Planar3DOverlay::setProperties(const QVariantMap& properties) {
|
||||
Base3DOverlay::setProperties(properties);
|
||||
|
||||
|
@ -67,7 +72,7 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve
|
|||
return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), getDimensions(), distance);
|
||||
}
|
||||
|
||||
Transform Planar3DOverlay::evalRenderTransform() const {
|
||||
Transform Planar3DOverlay::evalRenderTransform() {
|
||||
auto transform = getTransform();
|
||||
transform.setScale(1.0f); // ignore inherited scale factor from parents
|
||||
if (glm::length2(getDimensions()) != 1.0f) {
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
virtual glm::vec2 getSize() const { return _dimensions; };
|
||||
|
||||
glm::vec2 getDimensions() const { return _dimensions; }
|
||||
void setDimensions(float value) { _dimensions = glm::vec2(value); }
|
||||
void setDimensions(const glm::vec2& value) { _dimensions = value; }
|
||||
void setDimensions(float value) { setDimensions(glm::vec2(value)); }
|
||||
void setDimensions(const glm::vec2& value);
|
||||
|
||||
void setProperties(const QVariantMap& properties) override;
|
||||
QVariant getProperty(const QString& property) override;
|
||||
|
@ -33,10 +33,10 @@ public:
|
|||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||
|
||||
Transform evalRenderTransform() const override;
|
||||
|
||||
protected:
|
||||
glm::vec2 _dimensions;
|
||||
|
||||
Transform evalRenderTransform() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -124,3 +124,8 @@ void Rectangle3DOverlay::setProperties(const QVariantMap& properties) {
|
|||
Rectangle3DOverlay* Rectangle3DOverlay::createClone() const {
|
||||
return new Rectangle3DOverlay(this);
|
||||
}
|
||||
|
||||
Transform Rectangle3DOverlay::evalRenderTransform() {
|
||||
return getTransform();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@ public:
|
|||
void setProperties(const QVariantMap& properties) override;
|
||||
|
||||
virtual Rectangle3DOverlay* createClone() const override;
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
int _geometryCacheID;
|
||||
std::array<int, 4> _rectGeometryIds;
|
||||
|
|
|
@ -33,26 +33,15 @@ void Shape3DOverlay::render(RenderArgs* args) {
|
|||
const float MAX_COLOR = 255.0f;
|
||||
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform()
|
||||
// TODO: handle registration point??
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
auto batch = args->_batch;
|
||||
|
||||
if (batch) {
|
||||
Transform transform;
|
||||
transform.setTranslation(position);
|
||||
transform.setRotation(rotation);
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto shapePipeline = args->_shapePipeline;
|
||||
if (!shapePipeline) {
|
||||
shapePipeline = _isSolid ? geometryCache->getOpaqueShapePipeline() : geometryCache->getWireShapePipeline();
|
||||
}
|
||||
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
batch->setModelTransform(getRenderTransform());
|
||||
if (_isSolid) {
|
||||
geometryCache->renderSolidShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
|
||||
} else {
|
||||
|
@ -129,3 +118,16 @@ QVariant Shape3DOverlay::getProperty(const QString& property) {
|
|||
|
||||
return Volume3DOverlay::getProperty(property);
|
||||
}
|
||||
|
||||
Transform Shape3DOverlay::evalRenderTransform() {
|
||||
// TODO: handle registration point??
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
Transform transform;
|
||||
transform.setScale(dimensions);
|
||||
transform.setTranslation(position);
|
||||
transform.setRotation(rotation);
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ public:
|
|||
void setProperties(const QVariantMap& properties) override;
|
||||
QVariant getProperty(const QString& property) override;
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
float _borderSize;
|
||||
GeometryCache::Shape _shape { GeometryCache::Hexagon };
|
||||
|
|
|
@ -39,11 +39,7 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
|||
auto batch = args->_batch;
|
||||
|
||||
if (batch) {
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform()
|
||||
Transform transform = getTransform();
|
||||
transform.setScale(1.0f); // ignore inherited scale from SpatiallyNestable
|
||||
transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE);
|
||||
batch->setModelTransform(transform);
|
||||
batch->setModelTransform(getRenderTransform());
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto shapePipeline = args->_shapePipeline;
|
||||
|
@ -73,3 +69,11 @@ const render::ShapeKey Sphere3DOverlay::getShapeKey() {
|
|||
Sphere3DOverlay* Sphere3DOverlay::createClone() const {
|
||||
return new Sphere3DOverlay(this);
|
||||
}
|
||||
|
||||
Transform Sphere3DOverlay::evalRenderTransform() {
|
||||
Transform transform = getTransform();
|
||||
transform.setScale(1.0f); // ignore inherited scale from SpatiallyNestable
|
||||
transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ public:
|
|||
virtual const render::ShapeKey getShapeKey() override;
|
||||
|
||||
virtual Sphere3DOverlay* createClone() const override;
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -98,10 +98,7 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
Q_ASSERT(args->_batch);
|
||||
auto& batch = *args->_batch;
|
||||
|
||||
// FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform()
|
||||
Transform transform = getTransform();
|
||||
applyTransformTo(transform, true);
|
||||
setTransform(transform);
|
||||
auto transform = getRenderTransform();
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
|
@ -258,3 +255,8 @@ bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3
|
|||
setTransform(transform);
|
||||
return Billboard3DOverlay::findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
||||
}
|
||||
|
||||
Transform Text3DOverlay::evalRenderTransform() {
|
||||
return Parent::evalRenderTransform();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ class TextRenderer3D;
|
|||
|
||||
class Text3DOverlay : public Billboard3DOverlay {
|
||||
Q_OBJECT
|
||||
using Parent = Billboard3DOverlay;
|
||||
|
||||
public:
|
||||
static QString const TYPE;
|
||||
|
@ -64,6 +65,9 @@ public:
|
|||
|
||||
virtual Text3DOverlay* createClone() const override;
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
TextRenderer3D* _textRenderer = nullptr;
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@ AABox Volume3DOverlay::getBounds() const {
|
|||
return AABox(extents);
|
||||
}
|
||||
|
||||
void Volume3DOverlay::setDimensions(const glm::vec3& value) {
|
||||
_localBoundingBox.setBox(-value / 2.0f, value);
|
||||
notifyRenderTransformChange();
|
||||
}
|
||||
|
||||
void Volume3DOverlay::setProperties(const QVariantMap& properties) {
|
||||
Base3DOverlay::setProperties(properties);
|
||||
|
||||
|
@ -67,3 +72,11 @@ bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve
|
|||
// and testing intersection there.
|
||||
return _localBoundingBox.findRayIntersection(overlayFrameOrigin, overlayFrameDirection, distance, face, surfaceNormal);
|
||||
}
|
||||
|
||||
Transform Volume3DOverlay::evalRenderTransform() {
|
||||
Transform transform = getTransform();
|
||||
#ifndef USE_SN_SCALE
|
||||
transform.setScale(1.0f); // ignore any inherited scale from SpatiallyNestable
|
||||
#endif
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
class Volume3DOverlay : public Base3DOverlay {
|
||||
Q_OBJECT
|
||||
using Parent = Base3DOverlay;
|
||||
|
||||
public:
|
||||
Volume3DOverlay() {}
|
||||
|
@ -23,8 +24,8 @@ public:
|
|||
virtual AABox getBounds() const override;
|
||||
|
||||
const glm::vec3& getDimensions() const { return _localBoundingBox.getDimensions(); }
|
||||
void setDimensions(float value) { _localBoundingBox.setBox(glm::vec3(-value / 2.0f), value); }
|
||||
void setDimensions(const glm::vec3& value) { _localBoundingBox.setBox(-value / 2.0f, value); }
|
||||
void setDimensions(float value) { setDimensions(glm::vec3(value)); }
|
||||
void setDimensions(const glm::vec3& value);
|
||||
|
||||
void setProperties(const QVariantMap& properties) override;
|
||||
QVariant getProperty(const QString& property) override;
|
||||
|
@ -35,6 +36,8 @@ public:
|
|||
protected:
|
||||
// Centered local bounding box
|
||||
AABox _localBoundingBox{ vec3(0.0f), 1.0f };
|
||||
|
||||
Transform evalRenderTransform() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -286,7 +286,6 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
emit resizeWebSurface();
|
||||
}
|
||||
|
||||
vec2 halfSize = getSize() / 2.0f;
|
||||
vec4 color(toGlm(getColor()), getAlpha());
|
||||
|
||||
if (!_texture) {
|
||||
|
@ -302,8 +301,11 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
batch.setResourceTexture(0, _texture);
|
||||
|
||||
auto renderTransform = getRenderTransform();
|
||||
batch.setModelTransform(getRenderTransform());
|
||||
auto size = renderTransform.getScale();
|
||||
renderTransform.setScale(1.0f);
|
||||
batch.setModelTransform(renderTransform);
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
if (color.a < OPAQUE_ALPHA_THRESHOLD) {
|
||||
|
@ -311,10 +313,19 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
} else {
|
||||
geometryCache->bindWebBrowserProgram(batch);
|
||||
}
|
||||
|
||||
vec2 halfSize = vec2(size.x, size.y) / 2.0f;
|
||||
geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color, _geometryId);
|
||||
batch.setResourceTexture(0, nullptr); // restore default white color after me
|
||||
}
|
||||
|
||||
Transform Web3DOverlay::evalRenderTransform() {
|
||||
Transform transform = Parent::evalRenderTransform();
|
||||
transform.setScale(1.0f);
|
||||
transform.postScale(glm::vec3(getSize(), 1.0f));
|
||||
return transform;
|
||||
}
|
||||
|
||||
const render::ShapeKey Web3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias().withOwnPipeline();
|
||||
if (isTransparent()) {
|
||||
|
|
|
@ -76,6 +76,9 @@ signals:
|
|||
void requestWebSurface();
|
||||
void releaseWebSurface();
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
void setupQmlSurface();
|
||||
void rebuildWebSurface();
|
||||
|
|
|
@ -1078,4 +1078,4 @@ void EntityTreeRenderer::onEntityChanged(const EntityItemID& id) {
|
|||
_changedEntitiesGuard.withWriteLock([&] {
|
||||
_changedEntities.insert(id);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -228,18 +228,20 @@ void Model::updateRenderItems() {
|
|||
// We need to update them here so we can correctly update the bounding box.
|
||||
self->updateClusterMatrices();
|
||||
|
||||
Transform modelTransform = self->getTransform();
|
||||
Transform physicsTransform = modelTransform;
|
||||
modelTransform.setScale(glm::vec3(1.0f));
|
||||
|
||||
uint32_t deleteGeometryCounter = self->_deleteGeometryCounter;
|
||||
|
||||
render::Transaction transaction;
|
||||
foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [deleteGeometryCounter](ModelMeshPartPayload& data) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [deleteGeometryCounter, modelTransform](ModelMeshPartPayload& data) {
|
||||
ModelPointer model = data._model.lock();
|
||||
if (model && model->isLoaded()) {
|
||||
// Ensure the model geometry was not reset between frames
|
||||
if (deleteGeometryCounter == model->_deleteGeometryCounter) {
|
||||
Transform modelTransform = model->getTransform();
|
||||
modelTransform.setScale(glm::vec3(1.0f));
|
||||
|
||||
|
||||
const Model::MeshState& state = model->getMeshState(data._meshIndex);
|
||||
Transform renderTransform = modelTransform;
|
||||
if (state.clusterMatrices.size() == 1) {
|
||||
|
@ -254,11 +256,10 @@ void Model::updateRenderItems() {
|
|||
// collision mesh does not share the same unit scale as the FBX file's mesh: only apply offset
|
||||
Transform collisionMeshOffset;
|
||||
collisionMeshOffset.setIdentity();
|
||||
Transform modelTransform = self->getTransform();
|
||||
foreach(auto itemID, self->_collisionRenderItemsMap.keys()) {
|
||||
transaction.updateItem<MeshPartPayload>(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) {
|
||||
transaction.updateItem<MeshPartPayload>(itemID, [physicsTransform, collisionMeshOffset](MeshPartPayload& data) {
|
||||
// update the model transform for this render item.
|
||||
data.updateTransform(modelTransform, collisionMeshOffset);
|
||||
data.updateTransform(physicsTransform, collisionMeshOffset);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1306,55 +1307,6 @@ bool Model::isRenderable() const {
|
|||
return !_meshStates.isEmpty() || (isLoaded() && _renderGeometry->getMeshes().empty());
|
||||
}
|
||||
|
||||
bool Model::initWhenReady(const render::ScenePointer& scene) {
|
||||
// NOTE: this only called by SkeletonModel
|
||||
if (_addedToScene || !isRenderable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
createRenderItemSet();
|
||||
|
||||
render::Transaction transaction;
|
||||
|
||||
bool addedTransaction = false;
|
||||
if (_collisionGeometry) {
|
||||
foreach (auto renderItem, _collisionRenderItems) {
|
||||
auto item = scene->allocateID();
|
||||
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
||||
_collisionRenderItemsMap.insert(item, renderPayload);
|
||||
transaction.resetItem(item, renderPayload);
|
||||
}
|
||||
addedTransaction = !_collisionRenderItems.empty();
|
||||
} else {
|
||||
bool hasTransparent = false;
|
||||
size_t verticesCount = 0;
|
||||
foreach (auto renderItem, _modelMeshRenderItems) {
|
||||
auto item = scene->allocateID();
|
||||
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
||||
|
||||
hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent();
|
||||
verticesCount += renderItem.get()->getVerticesCount();
|
||||
_modelMeshRenderItemsMap.insert(item, renderPayload);
|
||||
transaction.resetItem(item, renderPayload);
|
||||
}
|
||||
addedTransaction = !_modelMeshRenderItemsMap.empty();
|
||||
_renderInfoVertexCount = verticesCount;
|
||||
_renderInfoDrawCalls = _modelMeshRenderItemsMap.count();
|
||||
_renderInfoHasTransparent = hasTransparent;
|
||||
}
|
||||
_addedToScene = addedTransaction;
|
||||
if (addedTransaction) {
|
||||
scene->enqueueTransaction(transaction);
|
||||
// NOTE: updateRender items enqueues identical transaction (using a lambda)
|
||||
// so it looks like we're doing double work here, but I don't want to remove the call
|
||||
// for fear there is some side effect we'll miss. -- Andrew 2016.07.21
|
||||
// TODO: figure out if we really need this call to updateRenderItems() or not.
|
||||
updateRenderItems();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class CollisionRenderGeometry : public Geometry {
|
||||
public:
|
||||
CollisionRenderGeometry(model::MeshPointer mesh) {
|
||||
|
|
|
@ -87,7 +87,6 @@ public:
|
|||
bool needsFixupInScene() const;
|
||||
|
||||
bool needsReload() const { return _needsReload; }
|
||||
bool initWhenReady(const render::ScenePointer& scene);
|
||||
bool addToScene(const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
auto getters = render::Item::Status::Getters(0);
|
||||
|
|
Loading…
Reference in a new issue