mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-15 21:36:59 +02:00
billboard mode working on most entity types
This commit is contained in:
parent
6e0bad814e
commit
bef0c79b67
28 changed files with 188 additions and 129 deletions
|
@ -2455,13 +2455,18 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value);
|
||||
});
|
||||
|
||||
EntityItem::setBillboardRotationOperator([](const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode, const glm::vec3& frustumPos) {
|
||||
EntityItem::setBillboardRotationOperator([](const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode, const glm::vec3& frustumPos, bool rotate90x) {
|
||||
const glm::quat ROTATE_90X = glm::angleAxis(-(float)M_PI_2, Vectors::RIGHT);
|
||||
if (billboardMode == BillboardMode::YAW) {
|
||||
//rotate about vertical to face the camera
|
||||
glm::vec3 dPosition = frustumPos - position;
|
||||
// If x and z are 0, atan(x, z) is undefined, so default to 0 degrees
|
||||
float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z);
|
||||
return glm::quat(glm::vec3(0.0f, yawRotation, 0.0f));
|
||||
glm::quat result = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f));
|
||||
if (rotate90x) {
|
||||
result *= ROTATE_90X;
|
||||
}
|
||||
return result;
|
||||
} else if (billboardMode == BillboardMode::FULL) {
|
||||
// use the referencial from the avatar, y isn't always up
|
||||
glm::vec3 avatarUP = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * Vectors::UP;
|
||||
|
@ -2470,7 +2475,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
// make sure s is not NaN for any component
|
||||
if (glm::length2(s) > 0.0f) {
|
||||
return glm::conjugate(glm::toQuat(glm::lookAt(frustumPos, position, avatarUP)));
|
||||
glm::quat result = glm::conjugate(glm::toQuat(glm::lookAt(frustumPos, position, avatarUP)));
|
||||
if (rotate90x) {
|
||||
result *= ROTATE_90X;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return rotation;
|
||||
|
|
|
@ -254,7 +254,8 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE);
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), true));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
// Background circle
|
||||
|
|
|
@ -103,6 +103,8 @@ void GridEntityRenderer::doRender(RenderArgs* args) {
|
|||
} else {
|
||||
transform.setTranslation(renderTransform.getTranslation());
|
||||
}
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch->setModelTransform(transform);
|
||||
|
||||
auto minCorner = glm::vec2(-0.5f, -0.5f);
|
||||
|
|
|
@ -97,7 +97,8 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
|
|||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch* batch = args->_batch;
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
|
||||
batch->setModelTransform(transform);
|
||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||
|
|
|
@ -47,8 +47,8 @@ void LineEntityRenderer::doRender(RenderArgs* args) {
|
|||
const auto& modelTransform = getModelTransform();
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(modelTransform.getTranslation());
|
||||
transform.setRotation(modelTransform.getRotation());
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch.setModelTransform(transform);
|
||||
if (_linePoints.size() > 1) {
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, false, false, true,
|
||||
|
|
|
@ -272,7 +272,8 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
|
|||
proceduralRender = true;
|
||||
}
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
if (!proceduralRender) {
|
||||
|
|
|
@ -455,7 +455,6 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) {
|
|||
color.finish = EntityRenderer::calculatePulseColor(_particleProperties.getColorFinish(), _pulseProperties, _created);
|
||||
color.spread = EntityRenderer::calculatePulseColor(_particleProperties.getColorSpread(), _pulseProperties, _created);
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
batch.setUniformBuffer(0, _uniformBuffer);
|
||||
|
|
|
@ -325,7 +325,8 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
|||
buildPipelines();
|
||||
}
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]);
|
||||
|
|
|
@ -238,53 +238,6 @@ void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxel
|
|||
startUpdates();
|
||||
}
|
||||
|
||||
glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const {
|
||||
glm::vec3 result;
|
||||
withReadLock([&] {
|
||||
glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units
|
||||
if (isEdged(_voxelSurfaceStyle)) {
|
||||
result = scale / -2.0f;
|
||||
}
|
||||
return scale / 2.0f;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const {
|
||||
glm::vec3 voxelVolumeSize;
|
||||
withReadLock([&] {
|
||||
voxelVolumeSize = _voxelVolumeSize;
|
||||
});
|
||||
|
||||
glm::vec3 dimensions = getScaledDimensions();
|
||||
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
|
||||
bool success; // TODO -- Does this actually have to happen in world space?
|
||||
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes
|
||||
glm::vec3 position = getWorldPosition(success);
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
|
||||
positionToCenter -= dimensions * Vectors::HALF - getSurfacePositionAdjustment();
|
||||
glm::mat4 centerToCorner = glm::translate(glm::mat4(), positionToCenter);
|
||||
glm::mat4 scaled = glm::scale(centerToCorner, scale);
|
||||
return scaled;
|
||||
}
|
||||
|
||||
glm::mat4 RenderablePolyVoxEntityItem::localToVoxelMatrix() const {
|
||||
glm::mat4 localToModelMatrix = glm::inverse(voxelToLocalMatrix());
|
||||
return localToModelMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 RenderablePolyVoxEntityItem::voxelToWorldMatrix() const {
|
||||
glm::mat4 rotation = glm::mat4_cast(getWorldOrientation());
|
||||
glm::mat4 translation = glm::translate(getWorldPosition());
|
||||
return translation * rotation * voxelToLocalMatrix();
|
||||
}
|
||||
|
||||
glm::mat4 RenderablePolyVoxEntityItem::worldToVoxelMatrix() const {
|
||||
glm::mat4 worldToModelMatrix = glm::inverse(voxelToWorldMatrix());
|
||||
return worldToModelMatrix;
|
||||
}
|
||||
|
||||
bool RenderablePolyVoxEntityItem::setVoxel(const ivec3& v, uint8_t toValue) {
|
||||
if (_locked) {
|
||||
return false;
|
||||
|
@ -582,7 +535,7 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
|||
return true;
|
||||
}
|
||||
|
||||
glm::mat4 wtvMatrix = worldToVoxelMatrix();
|
||||
glm::mat4 wtvMatrix = worldToVoxelMatrix(true);
|
||||
glm::vec3 normDirection = glm::normalize(direction);
|
||||
|
||||
// the PolyVox ray intersection code requires a near and far point.
|
||||
|
@ -623,7 +576,7 @@ bool RenderablePolyVoxEntityItem::findDetailedParabolaIntersection(const glm::ve
|
|||
return true;
|
||||
}
|
||||
|
||||
glm::mat4 wtvMatrix = worldToVoxelMatrix();
|
||||
glm::mat4 wtvMatrix = worldToVoxelMatrix(true);
|
||||
glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f);
|
||||
glm::vec4 velocityInVoxel = wtvMatrix * glm::vec4(velocity, 0.0f);
|
||||
glm::vec4 accelerationInVoxel = wtvMatrix * glm::vec4(acceleration, 0.0f);
|
||||
|
@ -1803,7 +1756,7 @@ ShapeKey PolyVoxEntityRenderer::getShapeKey() {
|
|||
|
||||
bool PolyVoxEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||
if (resultWithReadLock<bool>([&] {
|
||||
if (entity->voxelToWorldMatrix() != _lastVoxelToWorldMatrix) {
|
||||
if (entity->voxelToLocalMatrix() != _lastVoxelToLocalMatrix) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1829,7 +1782,9 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s
|
|||
}
|
||||
|
||||
void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||
_lastVoxelToWorldMatrix = entity->voxelToWorldMatrix();
|
||||
_lastVoxelToLocalMatrix = entity->voxelToLocalMatrix();
|
||||
_position = entity->getWorldPosition();
|
||||
_orientation = entity->getWorldOrientation();
|
||||
_lastVoxelVolumeSize = entity->getVoxelVolumeSize();
|
||||
_params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0));
|
||||
graphics::MeshPointer newMesh;
|
||||
|
@ -1862,17 +1817,18 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
|
||||
Transform transform(_lastVoxelToWorldMatrix);
|
||||
glm::mat4 rotation = glm::mat4_cast(EntityItem::getBillboardRotation(_position, _orientation, _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
Transform transform(glm::translate(_position) * rotation * _lastVoxelToLocalMatrix);
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
batch.setInputFormat(_vertexFormat);
|
||||
batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0,
|
||||
sizeof(PolyVox::PositionMaterialNormal));
|
||||
|
||||
|
||||
// TODO -- should we be setting this?
|
||||
// batch.setInputBuffer(gpu::Stream::NORMAL, mesh->getVertexBuffer()._buffer,
|
||||
// 12,
|
||||
|
|
|
@ -83,12 +83,6 @@ public:
|
|||
virtual void setVoxelVolumeSize(const glm::vec3& voxelVolumeSize) override;
|
||||
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) override;
|
||||
|
||||
glm::vec3 getSurfacePositionAdjustment() const;
|
||||
glm::mat4 voxelToWorldMatrix() const;
|
||||
glm::mat4 worldToVoxelMatrix() const;
|
||||
glm::mat4 voxelToLocalMatrix() const;
|
||||
glm::mat4 localToVoxelMatrix() const;
|
||||
|
||||
virtual ShapeType getShapeType() const override;
|
||||
virtual bool isReadyToComputeShape() const override;
|
||||
virtual void computeShapeInfo(ShapeInfo& info) override;
|
||||
|
@ -226,7 +220,9 @@ private:
|
|||
gpu::BufferPointer _params;
|
||||
std::array<NetworkTexturePointer, 3> _xyzTextures;
|
||||
glm::vec3 _lastVoxelVolumeSize;
|
||||
glm::mat4 _lastVoxelToWorldMatrix;
|
||||
glm::mat4 _lastVoxelToLocalMatrix;
|
||||
glm::vec3 _position;
|
||||
glm::quat _orientation;
|
||||
PolyVoxEntityItem::PolyVoxSurfaceStyle _lastSurfaceStyle { PolyVoxEntityItem::SURFACE_MARCHING_CUBES };
|
||||
std::array<QString, 3> _xyzTextureUrls;
|
||||
};
|
||||
|
|
|
@ -55,6 +55,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
void* key = (void*)this;
|
||||
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
|
||||
withWriteLock([&] {
|
||||
_shape = entity->getShape();
|
||||
_position = entity->getWorldPosition();
|
||||
_dimensions = entity->getUnscaledDimensions(); // get unscaled to avoid scaling twice
|
||||
_orientation = entity->getWorldOrientation();
|
||||
|
@ -69,7 +70,6 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
}
|
||||
|
||||
void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||
_shape = entity->getShape();
|
||||
_pulseProperties = entity->getPulseProperties();
|
||||
|
||||
bool materialChanged = false;
|
||||
|
@ -238,7 +238,10 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(),
|
||||
_shape < entity::Shape::Cube || _shape > entity::Shape::Icosahedron));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
if (pipelineType == Pipeline::PROCEDURAL) {
|
||||
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials.top().material);
|
||||
|
|
|
@ -131,7 +131,8 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
|
@ -312,7 +313,8 @@ void entities::TextPayload::render(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), textRenderable->_billboardMode, args->getViewFrustum().getPosition()));
|
||||
modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), textRenderable->_billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
|
||||
float scale = textRenderable->_lineHeight / textRenderer->getFontSize();
|
||||
modelTransform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z));
|
||||
|
|
|
@ -302,7 +302,8 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
batch.setResourceTexture(0, _texture);
|
||||
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
|
||||
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
// Turn off jitter for these entities
|
||||
|
|
|
@ -51,7 +51,7 @@ int EntityItem::_maxActionsDataSize = 800;
|
|||
quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND;
|
||||
QString EntityItem::_marketplacePublicKey;
|
||||
|
||||
std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode, const glm::vec3&)> EntityItem::_getBillboardRotationOperator = [](const glm::vec3&, const glm::quat& rotation, BillboardMode, const glm::vec3&) { return rotation; };
|
||||
std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode, const glm::vec3&, bool)> EntityItem::_getBillboardRotationOperator = [](const glm::vec3&, const glm::quat& rotation, BillboardMode, const glm::vec3&, bool) { return rotation; };
|
||||
std::function<glm::vec3()> EntityItem::_getPrimaryViewFrustumPositionOperator = []() { return glm::vec3(0.0f); };
|
||||
|
||||
EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||
|
|
|
@ -572,8 +572,8 @@ public:
|
|||
virtual void removeGrab(GrabPointer grab) override;
|
||||
virtual void disableGrab(GrabPointer grab) override;
|
||||
|
||||
static void setBillboardRotationOperator(std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode, const glm::vec3&)> getBillboardRotationOperator) { _getBillboardRotationOperator = getBillboardRotationOperator; }
|
||||
static glm::quat getBillboardRotation(const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode, const glm::vec3& frustumPos) { return _getBillboardRotationOperator(position, rotation, billboardMode, frustumPos); }
|
||||
static void setBillboardRotationOperator(std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode, const glm::vec3&, bool)> getBillboardRotationOperator) { _getBillboardRotationOperator = getBillboardRotationOperator; }
|
||||
static glm::quat getBillboardRotation(const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode, const glm::vec3& frustumPos, bool rotate90x = false) { return _getBillboardRotationOperator(position, rotation, billboardMode, frustumPos, rotate90x); }
|
||||
static void setPrimaryViewFrustumPositionOperator(std::function<glm::vec3()> getPrimaryViewFrustumPositionOperator) { _getPrimaryViewFrustumPositionOperator = getPrimaryViewFrustumPositionOperator; }
|
||||
static glm::vec3 getPrimaryViewFrustumPosition() { return _getPrimaryViewFrustumPositionOperator(); }
|
||||
|
||||
|
@ -788,7 +788,7 @@ protected:
|
|||
mutable bool _needsRenderUpdate { false };
|
||||
|
||||
private:
|
||||
static std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode, const glm::vec3&)> _getBillboardRotationOperator;
|
||||
static std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode, const glm::vec3&, bool)> _getBillboardRotationOperator;
|
||||
static std::function<glm::vec3()> _getPrimaryViewFrustumPositionOperator;
|
||||
};
|
||||
|
||||
|
|
|
@ -219,8 +219,10 @@ EntityItemID EntityTreeElement::evalDetailedRayIntersection(const glm::vec3& ori
|
|||
}
|
||||
|
||||
// extents is the entity relative, scaled, centered extents of the entity
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
||||
glm::mat4 translation = glm::translate(entity->getWorldPosition());
|
||||
glm::vec3 position = entity->getWorldPosition();
|
||||
glm::mat4 translation = glm::translate(position);
|
||||
glm::quat orientation = entity->getWorldOrientation();
|
||||
glm::mat4 rotation = glm::mat4_cast(EntityItem::getBillboardRotation(position, orientation, entity->getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition()));
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
|
@ -368,8 +370,10 @@ EntityItemID EntityTreeElement::evalDetailedParabolaIntersection(const glm::vec3
|
|||
}
|
||||
|
||||
// extents is the entity relative, scaled, centered extents of the entity
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
||||
glm::mat4 translation = glm::translate(entity->getWorldPosition());
|
||||
glm::vec3 position = entity->getWorldPosition();
|
||||
glm::mat4 translation = glm::translate(position);
|
||||
glm::quat orientation = entity->getWorldOrientation();
|
||||
glm::mat4 rotation = glm::mat4_cast(EntityItem::getBillboardRotation(position, orientation, entity->getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition()));
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
|
@ -472,8 +476,10 @@ void EntityTreeElement::evalEntitiesInSphere(const glm::vec3& position, float ra
|
|||
} else {
|
||||
// determine the worldToEntityMatrix that doesn't include scale because
|
||||
// we're going to use the registration aware aa box in the entity frame
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
||||
glm::mat4 translation = glm::translate(entity->getWorldPosition());
|
||||
glm::vec3 position = entity->getWorldPosition();
|
||||
glm::mat4 translation = glm::translate(position);
|
||||
glm::quat orientation = entity->getWorldOrientation();
|
||||
glm::mat4 rotation = glm::mat4_cast(EntityItem::getBillboardRotation(position, orientation, entity->getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition()));
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
|
@ -526,8 +532,10 @@ void EntityTreeElement::evalEntitiesInSphereWithType(const glm::vec3& position,
|
|||
} else {
|
||||
// determine the worldToEntityMatrix that doesn't include scale because
|
||||
// we're going to use the registration aware aa box in the entity frame
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
||||
glm::mat4 translation = glm::translate(entity->getWorldPosition());
|
||||
glm::vec3 position = entity->getWorldPosition();
|
||||
glm::mat4 translation = glm::translate(position);
|
||||
glm::quat orientation = entity->getWorldOrientation();
|
||||
glm::mat4 rotation = glm::mat4_cast(EntityItem::getBillboardRotation(position, orientation, entity->getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition()));
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
|
@ -585,8 +593,10 @@ void EntityTreeElement::evalEntitiesInSphereWithName(const glm::vec3& position,
|
|||
} else {
|
||||
// determine the worldToEntityMatrix that doesn't include scale because
|
||||
// we're going to use the registration aware aa box in the entity frame
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
||||
glm::mat4 translation = glm::translate(entity->getWorldPosition());
|
||||
glm::vec3 position = entity->getWorldPosition();
|
||||
glm::mat4 translation = glm::translate(position);
|
||||
glm::quat orientation = entity->getWorldOrientation();
|
||||
glm::mat4 rotation = glm::mat4_cast(EntityItem::getBillboardRotation(position, orientation, entity->getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition()));
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
|
|
|
@ -109,11 +109,9 @@ bool GizmoEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
|
|||
glm::vec3 dimensions = getScaledDimensions();
|
||||
glm::vec2 xyDimensions(dimensions.x, dimensions.z);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
rotation = glm::angleAxis(-(float)M_PI_2, rotation * Vectors::RIGHT) * rotation;
|
||||
rotation *= glm::angleAxis(-(float)M_PI_2, Vectors::RIGHT);
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
withReadLock([&] {
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
||||
});
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition(), false);
|
||||
|
||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||
glm::vec3 hitPosition = origin + (distance * direction);
|
||||
|
@ -146,8 +144,9 @@ bool GizmoEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin,
|
|||
glm::vec3 dimensions = getScaledDimensions();
|
||||
glm::vec2 xyDimensions(dimensions.x, dimensions.z);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
rotation = glm::angleAxis(-(float)M_PI_2, rotation * Vectors::RIGHT) * rotation;
|
||||
rotation *= glm::angleAxis(-(float)M_PI_2, Vectors::RIGHT);
|
||||
glm::vec3 position = getWorldPosition();
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition(), true);
|
||||
|
||||
glm::quat inverseRot = glm::inverse(rotation);
|
||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||
|
|
|
@ -125,6 +125,60 @@ void GridEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
|||
APPEND_ENTITY_PROPERTY(PROP_MINOR_GRID_EVERY, getMinorGridEvery());
|
||||
}
|
||||
|
||||
bool GridEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& element,
|
||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
glm::vec3 dimensions = getScaledDimensions();
|
||||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
||||
if (glm::dot(forward, direction) > 0.0f) {
|
||||
face = MAX_Z_FACE;
|
||||
surfaceNormal = -forward;
|
||||
} else {
|
||||
face = MIN_Z_FACE;
|
||||
surfaceNormal = forward;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GridEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration,
|
||||
OctreeElementPointer& element, float& parabolicDistance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
glm::vec3 dimensions = getScaledDimensions();
|
||||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
glm::quat inverseRot = glm::inverse(rotation);
|
||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||
glm::vec3 localVelocity = inverseRot * velocity;
|
||||
glm::vec3 localAcceleration = inverseRot * acceleration;
|
||||
|
||||
if (findParabolaRectangleIntersection(localOrigin, localVelocity, localAcceleration, xyDimensions, parabolicDistance)) {
|
||||
float localIntersectionVelocityZ = localVelocity.z + localAcceleration.z * parabolicDistance;
|
||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
||||
if (localIntersectionVelocityZ > 0.0f) {
|
||||
face = MIN_Z_FACE;
|
||||
surfaceNormal = forward;
|
||||
} else {
|
||||
face = MAX_Z_FACE;
|
||||
surfaceNormal = -forward;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GridEntityItem::setColor(const glm::u8vec3& color) {
|
||||
withWriteLock([&] {
|
||||
_needsRenderUpdate |= _color != color;
|
||||
|
|
|
@ -43,6 +43,16 @@ public:
|
|||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
virtual bool supportsDetailedIntersection() const override { return getBillboardMode() != BillboardMode::NONE; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||
virtual bool findDetailedParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity,
|
||||
const glm::vec3& acceleration, OctreeElementPointer& element, float& parabolicDistance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||
|
||||
static const uint32_t DEFAULT_MAJOR_GRID_EVERY;
|
||||
static const float DEFAULT_MINOR_GRID_EVERY;
|
||||
|
||||
|
|
|
@ -135,9 +135,7 @@ bool ImageEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
|
|||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
withReadLock([&] {
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
||||
});
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
||||
|
@ -161,9 +159,7 @@ bool ImageEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin,
|
|||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
withReadLock([&] {
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
||||
});
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
glm::quat inverseRot = glm::inverse(rotation);
|
||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
virtual bool supportsDetailedIntersection() const override { return true; }
|
||||
virtual bool supportsDetailedIntersection() const override { return getBillboardMode() != BillboardMode::NONE; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
|
|
|
@ -377,15 +377,21 @@ glm::mat4 PolyVoxEntityItem::localToVoxelMatrix() const {
|
|||
return localToModelMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 PolyVoxEntityItem::voxelToWorldMatrix() const {
|
||||
glm::mat4 rotation = glm::mat4_cast(getWorldOrientation());
|
||||
glm::mat4 translation = glm::translate(getWorldPosition());
|
||||
glm::mat4 PolyVoxEntityItem::voxelToWorldMatrix(bool includeBillboard) const {
|
||||
glm::quat orientation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition();
|
||||
glm::mat4 translation = glm::translate(position);
|
||||
glm::mat4 rotation;
|
||||
if (includeBillboard) {
|
||||
rotation = glm::mat4_cast(EntityItem::getBillboardRotation(position, orientation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition()));
|
||||
} else {
|
||||
rotation = glm::mat4_cast(orientation);
|
||||
}
|
||||
return translation * rotation * voxelToLocalMatrix();
|
||||
}
|
||||
|
||||
glm::mat4 PolyVoxEntityItem::worldToVoxelMatrix() const {
|
||||
glm::mat4 worldToModelMatrix = glm::inverse(voxelToWorldMatrix());
|
||||
return worldToModelMatrix;
|
||||
glm::mat4 PolyVoxEntityItem::worldToVoxelMatrix(bool includeBillboard) const {
|
||||
return glm::inverse(voxelToWorldMatrix(includeBillboard));
|
||||
}
|
||||
|
||||
glm::vec3 PolyVoxEntityItem::voxelCoordsToWorldCoords(const glm::vec3& voxelCoords) const {
|
||||
|
|
|
@ -167,8 +167,8 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
|
||||
bool isEdged() const;
|
||||
|
||||
glm::mat4 voxelToWorldMatrix() const;
|
||||
glm::mat4 worldToVoxelMatrix() const;
|
||||
glm::mat4 voxelToWorldMatrix(bool includeBillboard = false) const;
|
||||
glm::mat4 worldToVoxelMatrix(bool includeBillboard = false) const;
|
||||
glm::mat4 voxelToLocalMatrix() const;
|
||||
glm::mat4 localToVoxelMatrix() const;
|
||||
|
||||
|
|
|
@ -257,7 +257,8 @@ float ShapeEntityItem::getAlpha() const {
|
|||
|
||||
void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||
const float MAX_FLAT_DIMENSION = 0.0001f;
|
||||
if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) {
|
||||
const auto shape = getShape();
|
||||
if ((shape == entity::Shape::Circle || shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) {
|
||||
// enforce flatness in Y
|
||||
glm::vec3 newDimensions = value;
|
||||
newDimensions.y = MAX_FLAT_DIMENSION;
|
||||
|
@ -268,15 +269,24 @@ void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
|||
}
|
||||
|
||||
bool ShapeEntityItem::supportsDetailedIntersection() const {
|
||||
return _shape == entity::Sphere;
|
||||
return getShape() == entity::Sphere || getBillboardMode() != BillboardMode::NONE;
|
||||
}
|
||||
|
||||
bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& element,
|
||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
if (getShape() != entity::Sphere) {
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::vec3 dimensions = getScaledDimensions();
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
// determine the ray in the frame of the entity transformed from a unit sphere
|
||||
glm::mat4 entityToWorldMatrix = getEntityToWorldMatrix();
|
||||
glm::mat4 entityToWorldMatrix = glm::translate(position) * glm::mat4_cast(rotation) * glm::scale(dimensions);
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||
glm::vec3 entityFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f));
|
||||
|
@ -302,8 +312,17 @@ bool ShapeEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin,
|
|||
OctreeElementPointer& element, float& parabolicDistance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||
if (getShape() != entity::Sphere) {
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::vec3 dimensions = getScaledDimensions();
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
// determine the parabola in the frame of the entity transformed from a unit sphere
|
||||
glm::mat4 entityToWorldMatrix = getEntityToWorldMatrix();
|
||||
glm::mat4 entityToWorldMatrix = glm::translate(position) * glm::mat4_cast(rotation) * glm::scale(dimensions);
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||
glm::vec3 entityFrameVelocity = glm::vec3(worldToEntityMatrix * glm::vec4(velocity, 0.0f));
|
||||
|
@ -343,8 +362,9 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
// is set.
|
||||
|
||||
const glm::vec3 entityDimensions = getScaledDimensions();
|
||||
const auto shape = getShape();
|
||||
|
||||
switch (_shape){
|
||||
switch (shape){
|
||||
case entity::Shape::Quad:
|
||||
// Quads collide like flat Cubes
|
||||
case entity::Shape::Cube: {
|
||||
|
|
|
@ -199,9 +199,7 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
|
|||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
withReadLock([&] {
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
||||
});
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
||||
|
@ -225,9 +223,7 @@ bool TextEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, c
|
|||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
withReadLock([&] {
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
||||
});
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
glm::quat inverseRot = glm::inverse(rotation);
|
||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
virtual bool supportsDetailedIntersection() const override { return true; }
|
||||
virtual bool supportsDetailedIntersection() const override { return getBillboardMode() != BillboardMode::NONE; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
|
|
|
@ -165,9 +165,7 @@ bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const g
|
|||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
withReadLock([&] {
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
||||
});
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
||||
|
@ -192,9 +190,7 @@ bool WebEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, co
|
|||
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
|
||||
glm::quat rotation = getWorldOrientation();
|
||||
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||
withReadLock([&] {
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
||||
});
|
||||
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||
|
||||
glm::quat inverseRot = glm::inverse(rotation);
|
||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
virtual bool supportsDetailedIntersection() const override { return true; }
|
||||
virtual bool supportsDetailedIntersection() const override { return getBillboardMode() != BillboardMode::NONE; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
|
|
Loading…
Reference in a new issue