mirror of
https://github.com/overte-org/overte.git
synced 2025-07-03 21:29:16 +02:00
Merge branch 'master' of github.com:worklist/hifi
This commit is contained in:
commit
c5ad3331f9
10 changed files with 188 additions and 31 deletions
|
@ -1384,7 +1384,9 @@ Avatar* Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3
|
||||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||||
glm::vec3 headPosition = avatar->getHead().getPosition();
|
glm::vec3 headPosition = avatar->getHead().getPosition();
|
||||||
if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS * avatar->getScale())) {
|
float distance;
|
||||||
|
if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition,
|
||||||
|
HEAD_SPHERE_RADIUS * avatar->getScale(), distance)) {
|
||||||
eyePosition = avatar->getHead().getEyePosition();
|
eyePosition = avatar->getHead().getEyePosition();
|
||||||
_lookatIndicatorScale = avatar->getScale();
|
_lookatIndicatorScale = avatar->getScale();
|
||||||
_lookatOtherPosition = headPosition;
|
_lookatOtherPosition = headPosition;
|
||||||
|
@ -1722,6 +1724,40 @@ void Application::update(float deltaTime) {
|
||||||
_myAvatar.simulate(deltaTime, NULL, Menu::getInstance()->getGyroCameraSensitivity());
|
_myAvatar.simulate(deltaTime, NULL, Menu::getInstance()->getGyroCameraSensitivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no transmitter drive implies transmitter pick
|
||||||
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
|
||||||
|
_transmitterPickStart = _myAvatar.getSkeleton().joint[AVATAR_JOINT_CHEST].position;
|
||||||
|
glm::vec3 direction = _myAvatar.getOrientation() *
|
||||||
|
glm::quat(glm::radians(_myTransmitter.getEstimatedRotation())) * IDENTITY_FRONT;
|
||||||
|
|
||||||
|
// check against voxels, avatars
|
||||||
|
const float MAX_PICK_DISTANCE = 100.0f;
|
||||||
|
float minDistance = MAX_PICK_DISTANCE;
|
||||||
|
VoxelDetail detail;
|
||||||
|
float distance;
|
||||||
|
BoxFace face;
|
||||||
|
if (_voxels.findRayIntersection(_transmitterPickStart, direction, detail, distance, face)) {
|
||||||
|
minDistance = min(minDistance, distance);
|
||||||
|
}
|
||||||
|
for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||||
|
node->lock();
|
||||||
|
if (node->getLinkedData() != NULL) {
|
||||||
|
Avatar *avatar = (Avatar*)node->getLinkedData();
|
||||||
|
if (!avatar->isInitialized()) {
|
||||||
|
avatar->init();
|
||||||
|
}
|
||||||
|
if (avatar->findRayIntersection(_transmitterPickStart, direction, distance)) {
|
||||||
|
minDistance = min(minDistance, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node->unlock();
|
||||||
|
}
|
||||||
|
_transmitterPickEnd = _transmitterPickStart + direction * minDistance;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_transmitterPickStart = _transmitterPickEnd = glm::vec3();
|
||||||
|
}
|
||||||
|
|
||||||
if (!OculusManager::isConnected()) {
|
if (!OculusManager::isConnected()) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
||||||
|
@ -2271,6 +2307,27 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFollowIndicator();
|
renderFollowIndicator();
|
||||||
|
|
||||||
|
// render transmitter pick ray, if non-empty
|
||||||
|
if (_transmitterPickStart != _transmitterPickEnd) {
|
||||||
|
Glower glower;
|
||||||
|
const float TRANSMITTER_PICK_COLOR[] = { 1.0f, 1.0f, 0.0f };
|
||||||
|
glColor3fv(TRANSMITTER_PICK_COLOR);
|
||||||
|
glLineWidth(3.0f);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3f(_transmitterPickStart.x, _transmitterPickStart.y, _transmitterPickStart.z);
|
||||||
|
glVertex3f(_transmitterPickEnd.x, _transmitterPickEnd.y, _transmitterPickEnd.z);
|
||||||
|
glEnd();
|
||||||
|
glLineWidth(1.0f);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(_transmitterPickEnd.x, _transmitterPickEnd.y, _transmitterPickEnd.z);
|
||||||
|
|
||||||
|
const float PICK_END_RADIUS = 0.025f;
|
||||||
|
glutSolidSphere(PICK_END_RADIUS, 8, 8);
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::displayOverlay() {
|
void Application::displayOverlay() {
|
||||||
|
|
|
@ -298,6 +298,9 @@ private:
|
||||||
glm::vec3 _lookatOtherPosition;
|
glm::vec3 _lookatOtherPosition;
|
||||||
float _lookatIndicatorScale;
|
float _lookatIndicatorScale;
|
||||||
|
|
||||||
|
glm::vec3 _transmitterPickStart;
|
||||||
|
glm::vec3 _transmitterPickEnd;
|
||||||
|
|
||||||
bool _perfStatsOn; // Do we want to display perfStats?
|
bool _perfStatsOn; // Do we want to display perfStats?
|
||||||
|
|
||||||
ChatEntry _chatEntry; // chat entry field
|
ChatEntry _chatEntry; // chat entry field
|
||||||
|
|
|
@ -46,7 +46,6 @@ void OculusManager::updateYawOffset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) {
|
void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) {
|
||||||
yaw = pitch = roll = 0.0f;
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
_sensorFusion.GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
|
_sensorFusion.GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
|
||||||
|
|
||||||
|
|
|
@ -598,13 +598,35 @@ float loadSetting(QSettings* settings, const char* name, float defaultValue) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rayIntersectsSphere(glm::vec3& rayStarting, glm::vec3& rayNormalizedDirection, glm::vec3& sphereCenter, double sphereRadius) {
|
bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection,
|
||||||
glm::vec3 vecFromRayToSphereCenter = sphereCenter - rayStarting;
|
const glm::vec3& sphereCenter, float sphereRadius, float& distance) {
|
||||||
double projection = glm::dot(vecFromRayToSphereCenter, rayNormalizedDirection);
|
glm::vec3 relativeOrigin = rayStarting - sphereCenter;
|
||||||
double shortestDistance = sqrt(glm::dot(vecFromRayToSphereCenter, vecFromRayToSphereCenter) - projection * projection);
|
|
||||||
if (shortestDistance <= sphereRadius) {
|
// compute the b, c terms of the quadratic equation (a is dot(direction, direction), which is one)
|
||||||
return true;
|
float b = 2.0f * glm::dot(rayNormalizedDirection, relativeOrigin);
|
||||||
|
float c = glm::dot(relativeOrigin, relativeOrigin) - sphereRadius * sphereRadius;
|
||||||
|
|
||||||
|
// compute the radicand of the quadratic. if less than zero, there's no intersection
|
||||||
|
float radicand = b * b - 4.0f * c;
|
||||||
|
if (radicand < 0.0f) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute the first solution of the quadratic
|
||||||
|
float root = sqrtf(radicand);
|
||||||
|
float firstSolution = -b - root;
|
||||||
|
if (firstSolution > 0.0f) {
|
||||||
|
distance = firstSolution / 2.0f;
|
||||||
|
return true; // origin is outside the sphere
|
||||||
|
}
|
||||||
|
|
||||||
|
// now try the second solution
|
||||||
|
float secondSolution = -b + root;
|
||||||
|
if (secondSolution > 0.0f) {
|
||||||
|
distance = 0.0f;
|
||||||
|
return true; // origin is inside the sphere
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,4 +637,4 @@ bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadiu
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,8 @@ void runTimingTests();
|
||||||
|
|
||||||
float loadSetting(QSettings* settings, const char* name, float defaultValue);
|
float loadSetting(QSettings* settings, const char* name, float defaultValue);
|
||||||
|
|
||||||
bool rayIntersectsSphere(glm::vec3& rayStarting, glm::vec3& rayNormalizedDirection, glm::vec3& sphereCenter, double sphereRadius);
|
bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection,
|
||||||
|
const glm::vec3& sphereCenter, float sphereRadius, float& distance);
|
||||||
|
|
||||||
bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadius);
|
bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadius);
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,8 @@ Avatar::Avatar(Node* owningNode) :
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||||
_maxArmLength(0.0f),
|
_maxArmLength(0.0f),
|
||||||
_pelvisStandingHeight(0.0f)
|
_pelvisStandingHeight(0.0f),
|
||||||
|
_moving(false)
|
||||||
{
|
{
|
||||||
// give the pointer to our head to inherited _headData variable from AvatarData
|
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||||
_headData = &_head;
|
_headData = &_head;
|
||||||
|
@ -485,22 +486,27 @@ void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) {
|
||||||
// render a simple round on the ground projected down from the avatar's position
|
// render a simple round on the ground projected down from the avatar's position
|
||||||
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), _scale * 0.1f, 0.2f);
|
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), _scale * 0.1f, 0.2f);
|
||||||
|
|
||||||
// render body
|
{
|
||||||
renderBody(lookingInMirror, renderAvatarBalls);
|
// glow when moving
|
||||||
|
Glower glower(_moving ? 1.0f : 0.0f);
|
||||||
|
|
||||||
|
// render body
|
||||||
|
renderBody(lookingInMirror, renderAvatarBalls);
|
||||||
|
|
||||||
// render sphere when far away
|
// render sphere when far away
|
||||||
const float MAX_ANGLE = 10.f;
|
const float MAX_ANGLE = 10.f;
|
||||||
glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition();
|
glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition();
|
||||||
glm::vec3 delta = _height * (_head.getCameraOrientation() * IDENTITY_UP) / 2.f;
|
glm::vec3 delta = _height * (_head.getCameraOrientation() * IDENTITY_UP) / 2.f;
|
||||||
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
||||||
|
|
||||||
if (angle < MAX_ANGLE) {
|
if (angle < MAX_ANGLE) {
|
||||||
glColor4f(0.5f, 0.8f, 0.8f, 1.f - angle / MAX_ANGLE);
|
glColor4f(0.5f, 0.8f, 0.8f, 1.f - angle / MAX_ANGLE);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(_position.x, _position.y, _position.z);
|
glTranslatef(_position.x, _position.y, _position.z);
|
||||||
glScalef(_height / 2.f, _height / 2.f, _height / 2.f);
|
glScalef(_height / 2.f, _height / 2.f, _height / 2.f);
|
||||||
glutSolidSphere(1.2f + _head.getAverageLoudness() * .0005f, 20, 20);
|
glutSolidSphere(1.2f + _head.getAverageLoudness() * .0005f, 20, 20);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the balls
|
// Render the balls
|
||||||
|
@ -794,6 +800,30 @@ void Avatar::getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, gl
|
||||||
rotation = _bodyBall[jointID].rotation;
|
rotation = _bodyBall[jointID].rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
|
||||||
|
float minDistance = FLT_MAX;
|
||||||
|
for (int i = 0; i < NUM_AVATAR_BODY_BALLS; i++) {
|
||||||
|
float distance;
|
||||||
|
if (rayIntersectsSphere(origin, direction, _bodyBall[i].position, _bodyBall[i].radius, distance)) {
|
||||||
|
minDistance = min(minDistance, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (minDistance == FLT_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
distance = minDistance;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Avatar::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
|
// change in position implies movement
|
||||||
|
glm::vec3 oldPosition = _position;
|
||||||
|
int bytesRead = AvatarData::parseData(sourceBuffer, numBytes);
|
||||||
|
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
|
||||||
|
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::saveData(QSettings* set) {
|
void Avatar::saveData(QSettings* set) {
|
||||||
set->beginGroup("Avatar");
|
set->beginGroup("Avatar");
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,15 @@ public:
|
||||||
// Get the position/rotation of a single body ball
|
// Get the position/rotation of a single body ball
|
||||||
void getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, glm::quat& rotation) const;
|
void getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, glm::quat& rotation) const;
|
||||||
|
|
||||||
|
/// Checks for an intersection between the described ray and any of the avatar's body balls.
|
||||||
|
/// \param origin the origin of the ray
|
||||||
|
/// \param direction the unit direction vector
|
||||||
|
/// \param[out] distance the variable in which to store the distance to intersection
|
||||||
|
/// \return whether or not the ray intersected
|
||||||
|
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
|
||||||
|
|
||||||
|
virtual int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||||
|
|
||||||
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
|
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -219,6 +228,8 @@ protected:
|
||||||
float _stringLength;
|
float _stringLength;
|
||||||
AvatarVoxelSystem _voxels;
|
AvatarVoxelSystem _voxels;
|
||||||
|
|
||||||
|
bool _moving; ///< set when position is changing
|
||||||
|
|
||||||
// protected methods...
|
// protected methods...
|
||||||
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||||
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
|
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
|
||||||
|
|
|
@ -318,6 +318,10 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCam
|
||||||
_mode = AVATAR_MODE_INTERACTING;
|
_mode = AVATAR_MODE_INTERACTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update moving flag based on speed
|
||||||
|
const float MOVING_SPEED_THRESHOLD = 0.01f;
|
||||||
|
_moving = _speed > MOVING_SPEED_THRESHOLD;
|
||||||
|
|
||||||
// update position by velocity, and subtract the change added earlier for gravity
|
// update position by velocity, and subtract the change added earlier for gravity
|
||||||
_position += _velocity * deltaTime;
|
_position += _velocity * deltaTime;
|
||||||
|
|
||||||
|
@ -511,7 +515,13 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
||||||
|
|
||||||
if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON) {
|
if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||||
// Dont display body
|
// Dont display body
|
||||||
} else if (_head.getFace().isFullFrame()) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// glow when moving
|
||||||
|
Glower glower(_moving ? 1.0f : 0.0f);
|
||||||
|
|
||||||
|
if (_head.getFace().isFullFrame()) {
|
||||||
// Render the full-frame video
|
// Render the full-frame video
|
||||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||||
if (alpha > 0.0f) {
|
if (alpha > 0.0f) {
|
||||||
|
@ -1032,4 +1042,4 @@ void MyAvatar::setOrientation(const glm::quat& orientation) {
|
||||||
|
|
||||||
void MyAvatar::setNewScale(const float scale) {
|
void MyAvatar::setNewScale(const float scale) {
|
||||||
_newScale = scale;
|
_newScale = scale;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "ProgramObject.h"
|
#include "ProgramObject.h"
|
||||||
#include "RenderUtil.h"
|
#include "RenderUtil.h"
|
||||||
|
|
||||||
GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE), _isOddFrame(false) {
|
GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE), _isOddFrame(false), _intensity(0.0f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const {
|
QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const {
|
||||||
|
@ -70,12 +70,15 @@ void GlowEffect::prepare() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlowEffect::begin(float intensity) {
|
void GlowEffect::begin(float intensity) {
|
||||||
glBlendColor(0.0f, 0.0f, 0.0f, intensity);
|
// store the current intensity and add the new amount
|
||||||
_isEmpty = false;
|
_intensityStack.push(_intensity);
|
||||||
|
glBlendColor(0.0f, 0.0f, 0.0f, _intensity += intensity);
|
||||||
|
_isEmpty &= (_intensity == 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlowEffect::end() {
|
void GlowEffect::end() {
|
||||||
glBlendColor(0.0f, 0.0f, 0.0f, 0.0f);
|
// restore the saved intensity
|
||||||
|
glBlendColor(0.0f, 0.0f, 0.0f, _intensity = _intensityStack.pop());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void maybeBind(QOpenGLFramebufferObject* fbo) {
|
static void maybeBind(QOpenGLFramebufferObject* fbo) {
|
||||||
|
@ -268,3 +271,12 @@ void GlowEffect::cycleRenderMode() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Glower::Glower(float amount) {
|
||||||
|
Application::getInstance()->getGlowEffect()->begin(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
Glower::~Glower() {
|
||||||
|
Application::getInstance()->getGlowEffect()->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define __interface__GlowEffect__
|
#define __interface__GlowEffect__
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QStack>
|
||||||
|
|
||||||
class QOpenGLFramebufferObject;
|
class QOpenGLFramebufferObject;
|
||||||
|
|
||||||
|
@ -63,6 +64,17 @@ private:
|
||||||
|
|
||||||
bool _isEmpty; ///< set when nothing in the scene is currently glowing
|
bool _isEmpty; ///< set when nothing in the scene is currently glowing
|
||||||
bool _isOddFrame; ///< controls the alternation between texture targets in diffuse add mode
|
bool _isOddFrame; ///< controls the alternation between texture targets in diffuse add mode
|
||||||
|
|
||||||
|
float _intensity;
|
||||||
|
QStack<float> _intensityStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// RAII-style glow handler. Applies glow when in scope.
|
||||||
|
class Glower {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Glower(float amount = 1.0f);
|
||||||
|
~Glower();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__GlowEffect__) */
|
#endif /* defined(__interface__GlowEffect__) */
|
||||||
|
|
Loading…
Reference in a new issue