mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 06:53:01 +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);
|
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) {
|
if (billboardMode == BillboardMode::YAW) {
|
||||||
//rotate about vertical to face the camera
|
//rotate about vertical to face the camera
|
||||||
glm::vec3 dPosition = frustumPos - position;
|
glm::vec3 dPosition = frustumPos - position;
|
||||||
// If x and z are 0, atan(x, z) is undefined, so default to 0 degrees
|
// 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);
|
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) {
|
} else if (billboardMode == BillboardMode::FULL) {
|
||||||
// use the referencial from the avatar, y isn't always up
|
// use the referencial from the avatar, y isn't always up
|
||||||
glm::vec3 avatarUP = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * Vectors::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
|
// make sure s is not NaN for any component
|
||||||
if (glm::length2(s) > 0.0f) {
|
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;
|
return rotation;
|
||||||
|
|
|
@ -254,7 +254,8 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
|
||||||
geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE);
|
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);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
// Background circle
|
// Background circle
|
||||||
|
|
|
@ -103,6 +103,8 @@ void GridEntityRenderer::doRender(RenderArgs* args) {
|
||||||
} else {
|
} else {
|
||||||
transform.setTranslation(renderTransform.getTranslation());
|
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);
|
batch->setModelTransform(transform);
|
||||||
|
|
||||||
auto minCorner = glm::vec2(-0.5f, -0.5f);
|
auto minCorner = glm::vec2(-0.5f, -0.5f);
|
||||||
|
|
|
@ -97,7 +97,8 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
gpu::Batch* batch = 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->setModelTransform(transform);
|
||||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||||
|
|
|
@ -47,8 +47,8 @@ void LineEntityRenderer::doRender(RenderArgs* args) {
|
||||||
const auto& modelTransform = getModelTransform();
|
const auto& modelTransform = getModelTransform();
|
||||||
Transform transform = Transform();
|
Transform transform = Transform();
|
||||||
transform.setTranslation(modelTransform.getTranslation());
|
transform.setTranslation(modelTransform.getTranslation());
|
||||||
transform.setRotation(modelTransform.getRotation());
|
transform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), _billboardMode,
|
||||||
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? EntityItem::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition()));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
if (_linePoints.size() > 1) {
|
if (_linePoints.size() > 1) {
|
||||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, false, false, true,
|
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, false, false, true,
|
||||||
|
|
|
@ -272,7 +272,8 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
|
||||||
proceduralRender = true;
|
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);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
if (!proceduralRender) {
|
if (!proceduralRender) {
|
||||||
|
|
|
@ -455,7 +455,6 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) {
|
||||||
color.finish = EntityRenderer::calculatePulseColor(_particleProperties.getColorFinish(), _pulseProperties, _created);
|
color.finish = EntityRenderer::calculatePulseColor(_particleProperties.getColorFinish(), _pulseProperties, _created);
|
||||||
color.spread = EntityRenderer::calculatePulseColor(_particleProperties.getColorSpread(), _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.setModelTransform(transform);
|
||||||
|
|
||||||
batch.setUniformBuffer(0, _uniformBuffer);
|
batch.setUniformBuffer(0, _uniformBuffer);
|
||||||
|
|
|
@ -325,7 +325,8 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
||||||
buildPipelines();
|
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.setModelTransform(transform);
|
||||||
|
|
||||||
batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]);
|
batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]);
|
||||||
|
|
|
@ -238,53 +238,6 @@ void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxel
|
||||||
startUpdates();
|
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) {
|
bool RenderablePolyVoxEntityItem::setVoxel(const ivec3& v, uint8_t toValue) {
|
||||||
if (_locked) {
|
if (_locked) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -582,7 +535,7 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 wtvMatrix = worldToVoxelMatrix();
|
glm::mat4 wtvMatrix = worldToVoxelMatrix(true);
|
||||||
glm::vec3 normDirection = glm::normalize(direction);
|
glm::vec3 normDirection = glm::normalize(direction);
|
||||||
|
|
||||||
// the PolyVox ray intersection code requires a near and far point.
|
// the PolyVox ray intersection code requires a near and far point.
|
||||||
|
@ -623,7 +576,7 @@ bool RenderablePolyVoxEntityItem::findDetailedParabolaIntersection(const glm::ve
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 wtvMatrix = worldToVoxelMatrix();
|
glm::mat4 wtvMatrix = worldToVoxelMatrix(true);
|
||||||
glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f);
|
glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f);
|
||||||
glm::vec4 velocityInVoxel = wtvMatrix * glm::vec4(velocity, 0.0f);
|
glm::vec4 velocityInVoxel = wtvMatrix * glm::vec4(velocity, 0.0f);
|
||||||
glm::vec4 accelerationInVoxel = wtvMatrix * glm::vec4(acceleration, 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 {
|
bool PolyVoxEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||||
if (resultWithReadLock<bool>([&] {
|
if (resultWithReadLock<bool>([&] {
|
||||||
if (entity->voxelToWorldMatrix() != _lastVoxelToWorldMatrix) {
|
if (entity->voxelToLocalMatrix() != _lastVoxelToLocalMatrix) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1829,7 +1782,9 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||||
_lastVoxelToWorldMatrix = entity->voxelToWorldMatrix();
|
_lastVoxelToLocalMatrix = entity->voxelToLocalMatrix();
|
||||||
|
_position = entity->getWorldPosition();
|
||||||
|
_orientation = entity->getWorldOrientation();
|
||||||
_lastVoxelVolumeSize = entity->getVoxelVolumeSize();
|
_lastVoxelVolumeSize = entity->getVoxelVolumeSize();
|
||||||
_params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0));
|
_params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0));
|
||||||
graphics::MeshPointer newMesh;
|
graphics::MeshPointer newMesh;
|
||||||
|
@ -1862,17 +1817,18 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||||
gpu::Batch& batch = *args->_batch;
|
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.setModelTransform(transform);
|
||||||
|
|
||||||
batch.setInputFormat(_vertexFormat);
|
batch.setInputFormat(_vertexFormat);
|
||||||
batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0,
|
batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0,
|
||||||
sizeof(PolyVox::PositionMaterialNormal));
|
sizeof(PolyVox::PositionMaterialNormal));
|
||||||
|
|
||||||
|
|
||||||
// TODO -- should we be setting this?
|
// TODO -- should we be setting this?
|
||||||
// batch.setInputBuffer(gpu::Stream::NORMAL, mesh->getVertexBuffer()._buffer,
|
// batch.setInputBuffer(gpu::Stream::NORMAL, mesh->getVertexBuffer()._buffer,
|
||||||
// 12,
|
// 12,
|
||||||
|
|
|
@ -83,12 +83,6 @@ public:
|
||||||
virtual void setVoxelVolumeSize(const glm::vec3& voxelVolumeSize) override;
|
virtual void setVoxelVolumeSize(const glm::vec3& voxelVolumeSize) override;
|
||||||
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) 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 ShapeType getShapeType() const override;
|
||||||
virtual bool isReadyToComputeShape() const override;
|
virtual bool isReadyToComputeShape() const override;
|
||||||
virtual void computeShapeInfo(ShapeInfo& info) override;
|
virtual void computeShapeInfo(ShapeInfo& info) override;
|
||||||
|
@ -226,7 +220,9 @@ private:
|
||||||
gpu::BufferPointer _params;
|
gpu::BufferPointer _params;
|
||||||
std::array<NetworkTexturePointer, 3> _xyzTextures;
|
std::array<NetworkTexturePointer, 3> _xyzTextures;
|
||||||
glm::vec3 _lastVoxelVolumeSize;
|
glm::vec3 _lastVoxelVolumeSize;
|
||||||
glm::mat4 _lastVoxelToWorldMatrix;
|
glm::mat4 _lastVoxelToLocalMatrix;
|
||||||
|
glm::vec3 _position;
|
||||||
|
glm::quat _orientation;
|
||||||
PolyVoxEntityItem::PolyVoxSurfaceStyle _lastSurfaceStyle { PolyVoxEntityItem::SURFACE_MARCHING_CUBES };
|
PolyVoxEntityItem::PolyVoxSurfaceStyle _lastSurfaceStyle { PolyVoxEntityItem::SURFACE_MARCHING_CUBES };
|
||||||
std::array<QString, 3> _xyzTextureUrls;
|
std::array<QString, 3> _xyzTextureUrls;
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,6 +55,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
void* key = (void*)this;
|
void* key = (void*)this;
|
||||||
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
|
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
|
_shape = entity->getShape();
|
||||||
_position = entity->getWorldPosition();
|
_position = entity->getWorldPosition();
|
||||||
_dimensions = entity->getUnscaledDimensions(); // get unscaled to avoid scaling twice
|
_dimensions = entity->getUnscaledDimensions(); // get unscaled to avoid scaling twice
|
||||||
_orientation = entity->getWorldOrientation();
|
_orientation = entity->getWorldOrientation();
|
||||||
|
@ -69,7 +70,6 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||||
_shape = entity->getShape();
|
|
||||||
_pulseProperties = entity->getPulseProperties();
|
_pulseProperties = entity->getPulseProperties();
|
||||||
|
|
||||||
bool materialChanged = false;
|
bool materialChanged = false;
|
||||||
|
@ -238,7 +238,10 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
||||||
return;
|
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) {
|
if (pipelineType == Pipeline::PROCEDURAL) {
|
||||||
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials.top().material);
|
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials.top().material);
|
||||||
|
|
|
@ -131,7 +131,8 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
||||||
return;
|
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);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
@ -312,7 +313,8 @@ void entities::TextPayload::render(RenderArgs* args) {
|
||||||
return;
|
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();
|
float scale = textRenderable->_lineHeight / textRenderer->getFontSize();
|
||||||
modelTransform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z));
|
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);
|
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);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
// Turn off jitter for these entities
|
// Turn off jitter for these entities
|
||||||
|
|
|
@ -51,7 +51,7 @@ int EntityItem::_maxActionsDataSize = 800;
|
||||||
quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND;
|
quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND;
|
||||||
QString EntityItem::_marketplacePublicKey;
|
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); };
|
std::function<glm::vec3()> EntityItem::_getPrimaryViewFrustumPositionOperator = []() { return glm::vec3(0.0f); };
|
||||||
|
|
||||||
EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||||
|
|
|
@ -572,8 +572,8 @@ public:
|
||||||
virtual void removeGrab(GrabPointer grab) override;
|
virtual void removeGrab(GrabPointer grab) override;
|
||||||
virtual void disableGrab(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 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) { return _getBillboardRotationOperator(position, rotation, billboardMode, frustumPos); }
|
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 void setPrimaryViewFrustumPositionOperator(std::function<glm::vec3()> getPrimaryViewFrustumPositionOperator) { _getPrimaryViewFrustumPositionOperator = getPrimaryViewFrustumPositionOperator; }
|
||||||
static glm::vec3 getPrimaryViewFrustumPosition() { return _getPrimaryViewFrustumPositionOperator(); }
|
static glm::vec3 getPrimaryViewFrustumPosition() { return _getPrimaryViewFrustumPositionOperator(); }
|
||||||
|
|
||||||
|
@ -788,7 +788,7 @@ protected:
|
||||||
mutable bool _needsRenderUpdate { false };
|
mutable bool _needsRenderUpdate { false };
|
||||||
|
|
||||||
private:
|
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;
|
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
|
// extents is the entity relative, scaled, centered extents of the entity
|
||||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
glm::vec3 position = entity->getWorldPosition();
|
||||||
glm::mat4 translation = glm::translate(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 entityToWorldMatrix = translation * rotation;
|
||||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
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
|
// extents is the entity relative, scaled, centered extents of the entity
|
||||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
glm::vec3 position = entity->getWorldPosition();
|
||||||
glm::mat4 translation = glm::translate(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 entityToWorldMatrix = translation * rotation;
|
||||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||||
|
|
||||||
|
@ -472,8 +476,10 @@ void EntityTreeElement::evalEntitiesInSphere(const glm::vec3& position, float ra
|
||||||
} else {
|
} else {
|
||||||
// determine the worldToEntityMatrix that doesn't include scale because
|
// determine the worldToEntityMatrix that doesn't include scale because
|
||||||
// we're going to use the registration aware aa box in the entity frame
|
// we're going to use the registration aware aa box in the entity frame
|
||||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
glm::vec3 position = entity->getWorldPosition();
|
||||||
glm::mat4 translation = glm::translate(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 entityToWorldMatrix = translation * rotation;
|
||||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||||
|
|
||||||
|
@ -526,8 +532,10 @@ void EntityTreeElement::evalEntitiesInSphereWithType(const glm::vec3& position,
|
||||||
} else {
|
} else {
|
||||||
// determine the worldToEntityMatrix that doesn't include scale because
|
// determine the worldToEntityMatrix that doesn't include scale because
|
||||||
// we're going to use the registration aware aa box in the entity frame
|
// we're going to use the registration aware aa box in the entity frame
|
||||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
glm::vec3 position = entity->getWorldPosition();
|
||||||
glm::mat4 translation = glm::translate(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 entityToWorldMatrix = translation * rotation;
|
||||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||||
|
|
||||||
|
@ -585,8 +593,10 @@ void EntityTreeElement::evalEntitiesInSphereWithName(const glm::vec3& position,
|
||||||
} else {
|
} else {
|
||||||
// determine the worldToEntityMatrix that doesn't include scale because
|
// determine the worldToEntityMatrix that doesn't include scale because
|
||||||
// we're going to use the registration aware aa box in the entity frame
|
// we're going to use the registration aware aa box in the entity frame
|
||||||
glm::mat4 rotation = glm::mat4_cast(entity->getWorldOrientation());
|
glm::vec3 position = entity->getWorldPosition();
|
||||||
glm::mat4 translation = glm::translate(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 entityToWorldMatrix = translation * rotation;
|
||||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||||
|
|
||||||
|
|
|
@ -109,11 +109,9 @@ bool GizmoEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
|
||||||
glm::vec3 dimensions = getScaledDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec2 xyDimensions(dimensions.x, dimensions.z);
|
glm::vec2 xyDimensions(dimensions.x, dimensions.z);
|
||||||
glm::quat rotation = getWorldOrientation();
|
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()));
|
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));
|
||||||
withReadLock([&] {
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition(), false);
|
||||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||||
glm::vec3 hitPosition = origin + (distance * direction);
|
glm::vec3 hitPosition = origin + (distance * direction);
|
||||||
|
@ -146,8 +144,9 @@ bool GizmoEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin,
|
||||||
glm::vec3 dimensions = getScaledDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
glm::vec2 xyDimensions(dimensions.x, dimensions.z);
|
glm::vec2 xyDimensions(dimensions.x, dimensions.z);
|
||||||
glm::quat rotation = getWorldOrientation();
|
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();
|
glm::vec3 position = getWorldPosition();
|
||||||
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition(), true);
|
||||||
|
|
||||||
glm::quat inverseRot = glm::inverse(rotation);
|
glm::quat inverseRot = glm::inverse(rotation);
|
||||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||||
|
|
|
@ -125,6 +125,60 @@ void GridEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
||||||
APPEND_ENTITY_PROPERTY(PROP_MINOR_GRID_EVERY, getMinorGridEvery());
|
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) {
|
void GridEntityItem::setColor(const glm::u8vec3& color) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_needsRenderUpdate |= _color != color;
|
_needsRenderUpdate |= _color != color;
|
||||||
|
|
|
@ -43,6 +43,16 @@ public:
|
||||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||||
bool& somethingChanged) override;
|
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 uint32_t DEFAULT_MAJOR_GRID_EVERY;
|
||||||
static const float DEFAULT_MINOR_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::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()));
|
||||||
withReadLock([&] {
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
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::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()));
|
||||||
withReadLock([&] {
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
glm::quat inverseRot = glm::inverse(rotation);
|
glm::quat inverseRot = glm::inverse(rotation);
|
||||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||||
bool& somethingChanged) override;
|
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,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
|
|
|
@ -377,15 +377,21 @@ glm::mat4 PolyVoxEntityItem::localToVoxelMatrix() const {
|
||||||
return localToModelMatrix;
|
return localToModelMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 PolyVoxEntityItem::voxelToWorldMatrix() const {
|
glm::mat4 PolyVoxEntityItem::voxelToWorldMatrix(bool includeBillboard) const {
|
||||||
glm::mat4 rotation = glm::mat4_cast(getWorldOrientation());
|
glm::quat orientation = getWorldOrientation();
|
||||||
glm::mat4 translation = glm::translate(getWorldPosition());
|
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();
|
return translation * rotation * voxelToLocalMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 PolyVoxEntityItem::worldToVoxelMatrix() const {
|
glm::mat4 PolyVoxEntityItem::worldToVoxelMatrix(bool includeBillboard) const {
|
||||||
glm::mat4 worldToModelMatrix = glm::inverse(voxelToWorldMatrix());
|
return glm::inverse(voxelToWorldMatrix(includeBillboard));
|
||||||
return worldToModelMatrix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 PolyVoxEntityItem::voxelCoordsToWorldCoords(const glm::vec3& voxelCoords) const {
|
glm::vec3 PolyVoxEntityItem::voxelCoordsToWorldCoords(const glm::vec3& voxelCoords) const {
|
||||||
|
|
|
@ -167,8 +167,8 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
|
|
||||||
bool isEdged() const;
|
bool isEdged() const;
|
||||||
|
|
||||||
glm::mat4 voxelToWorldMatrix() const;
|
glm::mat4 voxelToWorldMatrix(bool includeBillboard = false) const;
|
||||||
glm::mat4 worldToVoxelMatrix() const;
|
glm::mat4 worldToVoxelMatrix(bool includeBillboard = false) const;
|
||||||
glm::mat4 voxelToLocalMatrix() const;
|
glm::mat4 voxelToLocalMatrix() const;
|
||||||
glm::mat4 localToVoxelMatrix() const;
|
glm::mat4 localToVoxelMatrix() const;
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,8 @@ float ShapeEntityItem::getAlpha() const {
|
||||||
|
|
||||||
void ShapeEntityItem::setUnscaledDimensions(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) {
|
const auto shape = getShape();
|
||||||
|
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;
|
||||||
|
@ -268,15 +269,24 @@ void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShapeEntityItem::supportsDetailedIntersection() const {
|
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,
|
bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElementPointer& element,
|
OctreeElementPointer& element,
|
||||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
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
|
// 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::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||||
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||||
glm::vec3 entityFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.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,
|
OctreeElementPointer& element, float& parabolicDistance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
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
|
// 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::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||||
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||||
glm::vec3 entityFrameVelocity = glm::vec3(worldToEntityMatrix * glm::vec4(velocity, 0.0f));
|
glm::vec3 entityFrameVelocity = glm::vec3(worldToEntityMatrix * glm::vec4(velocity, 0.0f));
|
||||||
|
@ -343,8 +362,9 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
// is set.
|
// is set.
|
||||||
|
|
||||||
const glm::vec3 entityDimensions = getScaledDimensions();
|
const glm::vec3 entityDimensions = getScaledDimensions();
|
||||||
|
const auto shape = getShape();
|
||||||
|
|
||||||
switch (_shape){
|
switch (shape){
|
||||||
case entity::Shape::Quad:
|
case entity::Shape::Quad:
|
||||||
// Quads collide like flat Cubes
|
// Quads collide like flat Cubes
|
||||||
case entity::Shape::Cube: {
|
case entity::Shape::Cube: {
|
||||||
|
|
|
@ -199,9 +199,7 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
|
||||||
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()));
|
||||||
withReadLock([&] {
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
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::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()));
|
||||||
withReadLock([&] {
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
glm::quat inverseRot = glm::inverse(rotation);
|
glm::quat inverseRot = glm::inverse(rotation);
|
||||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||||
bool& somethingChanged) override;
|
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,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
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::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()));
|
||||||
withReadLock([&] {
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) {
|
||||||
glm::vec3 forward = rotation * Vectors::FRONT;
|
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::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()));
|
||||||
withReadLock([&] {
|
rotation = EntityItem::getBillboardRotation(position, rotation, getBillboardMode(), EntityItem::getPrimaryViewFrustumPosition());
|
||||||
rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition());
|
|
||||||
});
|
|
||||||
|
|
||||||
glm::quat inverseRot = glm::inverse(rotation);
|
glm::quat inverseRot = glm::inverse(rotation);
|
||||||
glm::vec3 localOrigin = inverseRot * (origin - position);
|
glm::vec3 localOrigin = inverseRot * (origin - position);
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||||
bool& somethingChanged) override;
|
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,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
|
|
Loading…
Reference in a new issue