JD2022-TU1/main/extern/Hue/examples/StreamTest/EffectPlayer.cpp

477 lines
No EOL
14 KiB
C++

/*******************************************************************************
Copyright © 2017 Philips Lighting Holding B.V.
All Rights Reserved.
********************************************************************************/
#include "stdafx.h"
#include <math.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
#include <huestream/huestream.h>
#include <huestream/effect/specialized/DynamicSceneEffect.h>
#include <huestream/effect/specialized/ExplosionEffect.h>
#include <huestream/effect/specialized/SequenceEffect.h>
#include <huestream/effect/animation/data/Playables/PlayableRandomizer.h>
#include "EffectPlayer.h"
#include "huestream/effect/animation/data/Channel.h"
#include "huestream/effect/specialized/MultiChannelEffect.h"
using namespace std;
using namespace std::chrono;
using namespace huestream;
EffectPlayer::EffectPlayer()
{
m_hueStream = HueStream::GetInstance();
m_speed = 1.0;
m_running = false;
m_speedAnimation = make_shared<PlayableConstant>(1.0);
m_alpha_saw = make_shared<PlayableConstant>(1);
m_alpha_square = make_shared<PlayableConstant>(1);
m_alpha_sine = make_shared<PlayableConstant>(1);
m_alpha_marquee = make_shared<PlayableConstant>(1);
m_alpha_colorloop = make_shared<PlayableConstant>(1);
m_alpha_fireballs = make_shared<PlayableConstant>(1);
m_alpha_police = make_shared<PlayableConstant>(1);
}
void EffectPlayer::SetSpeed(double speed) {
m_cs.Lock();
m_speed = speed;
m_cs.Unlock();
m_hueStream->LockEngine();
m_speedAnimation->SetValue(speed);
m_hueStream->UnlockEngine();
}
void EffectPlayer::PlayExplosion() {
Start();
static auto s_explosionCount = 0;
std::string name = "BAM!" + std::to_string(s_explosionCount++);
m_hueStream->LockEngine();
auto explosion = make_shared<ExplosionEffect>(name, 9);
auto color = Color(1.0, 0.7, 0.3);
auto radius = 2.0;
auto speed = GetSpeed();
auto expAlpha = 150 / speed;
auto expRadius = 250 / speed;
auto duration = 1500 / speed;
auto location = Location(0.0, 0.0);
explosion->PrepareEffect(color, location, radius, duration, expAlpha, expRadius);
m_hueStream->AddEffect(explosion);
explosion->Enable();
m_hueStream->UnlockEngine();
PlaySoundA((LPCSTR)"explosion.wav",
NULL, SND_FILENAME | SND_ASYNC);
}
void EffectPlayer::PlayRedWhiteBlue() {
Start();
static auto s_rwbCount = 0;
std::string name = "rwb" + std::to_string(s_rwbCount++);
m_hueStream->LockEngine();
auto animation = make_shared<PlayableSequence>(0);
auto slowUp = make_shared<PlayableTween>(0, 1, 2500, TweenType::Linear);
auto fastDown = make_shared<PlayableTween>(1, 0.5, 500, TweenType::Linear);
auto fastUp = make_shared<PlayableTween>(0.5, 1, 500, TweenType::Linear);
auto fastDownUpRepeated = make_shared<PlayableSequence>(3);
fastDownUpRepeated->Append(fastDown, "FastDown");
fastDownUpRepeated->Append(fastUp, "FastUp");
auto slowDown = make_shared<PlayableTween>(1, 0, 2500, TweenType::Linear);
animation->Append(slowUp, "SlowUp");
animation->Append(fastDownUpRepeated, "FastDownUp");
animation->Append(slowDown, "SlowDown");
auto zero = make_shared<PlayableConstant>(0);
auto one = make_shared<PlayableConstant>(1);
auto redChannel = make_shared<Channel>(Location(-(2.0 / 3.0), 0), animation, zero, zero, one);
auto whiteChannel = make_shared<Channel>(Location(0, 0), animation, animation, animation, one);
auto blueChannel = make_shared<Channel>(Location((2.0 / 3.0), 0), zero, zero, animation, one);
auto rwbEffect = make_shared<MultiChannelEffect>(name, 0);
rwbEffect->AddChannel(redChannel);
rwbEffect->AddChannel(whiteChannel);
rwbEffect->AddChannel(blueChannel);
rwbEffect->SetSpeedAnimation(m_speedAnimation);
m_hueStream->AddEffect(rwbEffect);
rwbEffect->Enable();
m_hueStream->UnlockEngine();
}
void EffectPlayer::PlayCombi() {
Start();
static auto s_combiCount = 0;
std::string bcName = "Saw" + std::to_string(s_combiCount++);
std::string lsName = "RandomFlash" + std::to_string(s_combiCount);
m_hueStream->LockEngine();
auto bcEffect = make_shared<AreaEffect>(bcName, 0);
auto b = make_shared<PlayableSequence>(4);
b->Append(make_shared<PlayableTween>(0, 1, 1000, TweenType::Linear), "Up");
b->Append(make_shared<PlayableTween>(1, 0, 1000, TweenType::Linear), "Down");
auto g = make_shared<PlayableConstant>(0);
auto r = make_shared<PlayableConstant>(0);
bcEffect->SetColorAnimation(r, g, b);
bcEffect->AddArea(Area::All);
bcEffect->SetSpeedAnimation(m_speedAnimation);
auto lsEffect = make_shared<LightSourceEffect>(lsName, 1);
auto length = 8000;
auto i = make_shared<PlayableRandomizer>(0.1, 1, 200, 400, TweenType::Linear, length);
lsEffect->SetColorAnimation(i, i, i);
lsEffect->SetRadiusAnimation(i);
auto x = make_shared<PlayableRandomizer>(-1, 1, 500, 1000, TweenType::Linear, length);
auto y = make_shared<PlayableRandomizer>(-1, 1, 500, 1000, TweenType::Linear, length);
lsEffect->SetPositionAnimation(x, y);
lsEffect->SetOpacityAnimation(make_shared<PlayableConstant>(0.8));
lsEffect->SetSpeedAnimation(m_speedAnimation);
m_hueStream->AddEffect(bcEffect);
m_hueStream->AddEffect(lsEffect);
bcEffect->Enable();
lsEffect->Enable();
m_hueStream->UnlockEngine();
}
void EffectPlayer::PlaySequenceRound() {
Start();
AfxBeginThread(SequenceRound, (LPVOID)this);
}
void EffectPlayer::PlaySequenceLtoR() {
Start();
AfxBeginThread(SequenceLtoR, (LPVOID)this);
}
void EffectPlayer::PlaySequenceFtoB() {
Start();
AfxBeginThread(SequenceFtoB, (LPVOID)this);
}
UINT EffectPlayer::SequenceRound(LPVOID pParam) {
EffectPlayer* self = (EffectPlayer*)pParam;
auto hueStream = self->m_hueStream;
static auto s_roundeffectCount = 0;
std::string name = "RoundSeq" + std::to_string(s_roundeffectCount++);
hueStream->LockEngine();
auto effect = std::make_shared<SequenceEffect>(name, 1);
effect->SetMode(SequenceModeRound);
effect->AddColor(Color(1, 1, 0));
effect->AddColor(Color(0, 1, 1));
effect->AddColor(Color(1, 0, 1));
effect->AddColor(Color(1, 0, 0));
effect->AddColor(Color(0, 1, 0));
effect->SetBri(10.0);
hueStream->AddEffect(effect);
effect->Enable();
hueStream->UnlockEngine();
for (int i = 0; i < 30; i++) {
hueStream->LockEngine();
effect->Step();
hueStream->UnlockEngine();
auto waitTime = (int)round(500.0 / self->GetSpeed());
std::unique_lock<std::mutex> lk(self->m_cv_mutex);
self->m_cv.wait_until(lk, system_clock::now() + milliseconds(waitTime));
if (!self->IsRunning()) {
break;
}
}
hueStream->LockEngine();
effect->Disable();
hueStream->UnlockEngine();
return 0;
}
UINT EffectPlayer::SequenceLtoR(LPVOID pParam) {
EffectPlayer* self = (EffectPlayer*)pParam;
auto hueStream = self->m_hueStream;
static auto s_leftRightSeqCount = 0;
std::string name = "LeftRightSeq" + std::to_string(s_leftRightSeqCount++);
hueStream->LockEngine();
auto effect = std::make_shared<SequenceEffect>(name, 1);
effect->SetMode(SequenceModeLeftRight);
effect->AddColor(Color(1, 1, 0));
effect->AddColor(Color(0, 1, 1));
effect->AddColor(Color(1, 0, 1));
effect->AddColor(Color(1, 0, 0));
effect->AddColor(Color(0, 1, 0));
hueStream->AddEffect(effect);
effect->Enable();
hueStream->UnlockEngine();
for (int i = 0; i < 30; i++) {
hueStream->LockEngine();
effect->Step();
hueStream->UnlockEngine();
auto waitTime = (int)round(500.0 / self->GetSpeed());
std::unique_lock<std::mutex> lk(self->m_cv_mutex);
self->m_cv.wait_until(lk, system_clock::now() + milliseconds(waitTime));
if (!self->IsRunning()) {
break;
}
}
hueStream->LockEngine();
effect->Disable();
hueStream->UnlockEngine();
return 0;
}
UINT EffectPlayer::SequenceFtoB(LPVOID pParam) {
EffectPlayer* self = (EffectPlayer*)pParam;
auto hueStream = self->m_hueStream;
static auto s_frontbackSeqCount = 0;
std::string name = "frontbackSeq" + std::to_string(s_frontbackSeqCount++);
hueStream->LockEngine();
auto effect = std::make_shared<SequenceEffect>(name, 1);
effect->SetMode(SequenceModeFrontBack);
effect->AddColor(Color(1, 0, 0));
effect->AddColor(Color(0, 1, 0));
effect->AddColor(Color(0, 0, 1));
hueStream->AddEffect(effect);
effect->Enable();
hueStream->UnlockEngine();
for (int i = 0; i < 30; i++) {
hueStream->LockEngine();
effect->Step();
hueStream->UnlockEngine();
auto waitTime = (int)round(500.0 / self->GetSpeed());
std::unique_lock<std::mutex> lk(self->m_cv_mutex);
self->m_cv.wait_until(lk, system_clock::now() + milliseconds(waitTime));
if (!self->IsRunning()) {
break;
}
}
hueStream->LockEngine();
effect->Disable();
hueStream->UnlockEngine();
return 0;
}
void EffectPlayer::SetSawEnabled(bool enabled) {
if (enabled) {
Start();
m_hueStream->LockEngine();
if (m_saw == nullptr) {
m_saw = std::make_shared<huestream::BrightnessSawEffect>("Saw", 8);
m_saw->PrepareEffect(m_speedAnimation, m_alpha_saw);
m_hueStream->AddEffect(m_saw);
}
m_saw->Enable();
m_hueStream->UnlockEngine();
} else if (m_saw != nullptr) {
m_hueStream->LockEngine();
m_saw->Disable();
m_hueStream->UnlockEngine();
}
}
void EffectPlayer::SetSquareEnabled(bool enabled) {
if (enabled) {
Start();
m_hueStream->LockEngine();
if (m_square == nullptr) {
m_square = std::make_shared<huestream::BrightnessSquareWaveEffect>("Square", 7);
m_square->PrepareEffect(m_speedAnimation, m_alpha_square);
m_hueStream->AddEffect(m_square);
}
m_square->Enable();
m_hueStream->UnlockEngine();
} else if (m_square != nullptr) {
m_hueStream->LockEngine();
m_square->Disable();
m_hueStream->UnlockEngine();
}
}
void EffectPlayer::SetSineEnabled(bool enabled) {
if (enabled) {
Start();
m_hueStream->LockEngine();
if (m_sine == nullptr) {
m_sine = std::make_shared<huestream::RGBSineEffect>("Sine", 6);
m_sine->PrepareEffect(m_speedAnimation, m_alpha_sine);
m_hueStream->AddEffect(m_sine);
}
m_sine->Enable();
m_hueStream->UnlockEngine();
} else if (m_sine != nullptr) {
m_hueStream->LockEngine();
m_sine->Disable();
m_hueStream->UnlockEngine();
}
}
void EffectPlayer::SetColorloopEnabled(bool enabled) {
if (enabled) {
Start();
m_hueStream->LockEngine();
if (m_colorloop == nullptr) {
m_colorloop = std::make_shared<huestream::ColorloopEffect>("Colorloop", 5);
m_colorloop->PrepareEffect(m_speedAnimation, m_alpha_colorloop);
m_hueStream->AddEffect(m_colorloop);
}
m_colorloop->Enable();
m_hueStream->UnlockEngine();
} else if (m_colorloop != nullptr) {
m_hueStream->LockEngine();
m_colorloop->Disable();
m_hueStream->UnlockEngine();
}
}
void EffectPlayer::SetMarqueeEnabled(bool enabled) {
if (enabled) {
Start();
m_hueStream->LockEngine();
if (m_marquee == nullptr) {
m_marquee = std::make_shared<huestream::LightpointMarqueeEffect>("Marquee", 4);
m_marquee->PrepareEffect(m_speedAnimation, m_alpha_marquee);
m_hueStream->AddEffect(m_marquee);
}
m_marquee->Enable();
m_hueStream->UnlockEngine();
} else if (m_marquee != nullptr) {
m_hueStream->LockEngine();
m_marquee->Disable();
m_hueStream->UnlockEngine();
}
}
void EffectPlayer::SetFireballsEnabled(bool enabled) {
if (enabled) {
Start();
m_hueStream->LockEngine();
if (m_fireballs == nullptr) {
m_fireballs = std::make_shared<huestream::FireballsEffect>("Fireballs", 3);
m_fireballs->PrepareEffect(m_speedAnimation, m_alpha_fireballs);
m_hueStream->AddEffect(m_fireballs);
}
m_fireballs->Enable();
m_hueStream->UnlockEngine();
}
else if (m_fireballs != nullptr) {
m_hueStream->LockEngine();
m_fireballs->Disable();
m_hueStream->UnlockEngine();
}
}
void EffectPlayer::SetPoliceEnabled(bool enabled) {
if (enabled) {
Start();
m_hueStream->LockEngine();
if (m_police_left == nullptr) {
m_police_left = std::make_shared<huestream::AreaEffect>("PoliceLeft", 2);
m_police_left->AddArea(Area::LeftHalf);
auto animationLeft = std::make_shared<PlayableSequence>(INF);
animationLeft->Append(std::make_shared<PlayableTween>(0.2, 1, 160, TweenType::Linear));
animationLeft->Append(std::make_shared<PlayableTween>(1, 1, 160, TweenType::Linear));
animationLeft->Append(std::make_shared<PlayableTween>(1, 0.2, 160, TweenType::Linear));
animationLeft->Append(std::make_shared<PlayableTween>(0.2, 0.1, 160, TweenType::Linear));
m_police_left->SetColorAnimation(animationLeft,std::make_shared<PlayableConstant>(0),std::make_shared<PlayableConstant>(0));
m_police_left->SetOpacityAnimation(m_alpha_fireballs);
m_police_left->SetSpeedAnimation(m_speedAnimation);
m_hueStream->AddEffect(m_police_left);
}
if (m_police_right == nullptr) {
m_police_right = std::make_shared<huestream::AreaEffect>("PoliceRight", 2);
m_police_right->AddArea(Area::RightHalf);
auto animationRight = std::make_shared<PlayableSequence>(INF);
animationRight->Append(std::make_shared<PlayableTween>(1, 0.2, 160, TweenType::Linear));
animationRight->Append(std::make_shared<PlayableTween>(0.2, 0.1, 160, TweenType::Linear));
animationRight->Append(std::make_shared<PlayableTween>(0.2, 1, 160, TweenType::Linear));
animationRight->Append(std::make_shared<PlayableTween>(1, 1, 160, TweenType::Linear));
m_police_right->SetColorAnimation(std::make_shared<PlayableConstant>(0),std::make_shared<PlayableConstant>(0),animationRight);
m_police_left->SetOpacityAnimation(m_alpha_fireballs);
m_police_right->SetSpeedAnimation(m_speedAnimation);
m_hueStream->AddEffect(m_police_right);
}
m_police_left->Enable();
m_police_right->Enable();
m_hueStream->UnlockEngine();
}
else if (m_police_left != nullptr && m_police_right != nullptr) {
m_hueStream->LockEngine();
m_police_left->Disable();
m_police_right->Disable();
m_hueStream->UnlockEngine();
}
}
double EffectPlayer::GetSpeed() {
m_cs.Lock();
auto speed = m_speed;
m_cs.Unlock();
return speed;
}
void EffectPlayer::Start()
{
m_cs.Lock();
m_running = true;
m_cs.Unlock();
m_hueStream->StartAsync();
}
void EffectPlayer::Stop()
{
m_running = false;
m_cv.notify_all();
m_hueStream->Stop();
m_marquee = nullptr;
}
bool EffectPlayer::IsRunning() {
m_cs.Lock();
auto running = m_running;
m_cs.Unlock();
return running;
}