Adding ViroKit. Needs AWSCore :(

This commit is contained in:
John Lyon-Smith
2018-03-27 17:46:15 -07:00
parent 2ab15e7dc1
commit 02e06dface
844 changed files with 86921 additions and 21 deletions

View File

@@ -0,0 +1,229 @@
//
// VROParticleModifier.h
// ViroRenderer
//
// Copyright © 2017 Viro Media. All rights reserved.
//
#ifndef VROParticleModifier_h
#define VROParticleModifier_h
#include <memory>
#include <vector>
#include <algorithm>
#include "VROMatrix4f.h"
#include "VROVector4f.h"
#include "VROOpenGL.h"
#include "VROVector3f.h"
#include "VROParticle.h"
#include "VROMath.h"
#include "VROStringUtil.h"
/*
VROParticleModifier contains a list of VROModifierIntervals to interpolate against with
referenceFactor to time, distance or velocity (as defined by a given VROModifierFactor). This
is used by VROParticleEmitter to pre-define a set of particle property behaviors (color,
scale, rotation, etc) that can then be applied to any particle.
*/
class VROParticleModifier {
public:
/*
VROModifierFactor represents the referenceFactor factor this modifier will interpolate against.
*/
enum class VROModifierFactor {
Time, // Interpolate against the timeSinceSpawnedInMs of a particle.
Distance, // Interpolate against the distanceTravelled of a particle.
Velocity // Interpolate against the current velocity of a particle.
};
static VROModifierFactor getModifierFactorForString(std::string strType) {
if (VROStringUtil::strcmpinsensitive(strType, "Velocity")) {
return VROModifierFactor::Velocity;
} else if (VROStringUtil::strcmpinsensitive(strType, "Distance")) {
return VROModifierFactor::Distance;
} else {
return VROModifierFactor::Time;
}
}
/*
Interpolation points between which to animate a given initial value (most likely the
particle's property value) towards.
*/
struct VROModifierInterval {
// Property of the particle to interpolate towards for this given VROModifierWindow.
VROVector3f targetedValue;
// Start and End factor values. For example, startTime and endTime.
double startFactor;
double endFactor;
bool operator < (const VROModifierInterval& point) const {
return (endFactor <= point.startFactor);
}
};
VROParticleModifier(VROVector3f constant) {
init(constant, constant, VROModifierFactor::Time);
};
VROParticleModifier(VROVector3f minRange, VROVector3f maxRange) {
init(minRange, maxRange, VROModifierFactor::Time);
};
VROParticleModifier(VROVector3f minRange, VROVector3f maxRange,
VROModifierFactor factor, std::vector<VROModifierInterval> values) {
init(minRange, maxRange, factor);
setInterpolatedPoints(values);
};
virtual ~VROParticleModifier(){};
VROVector3f getInitialValue() {
return random(_initialMinValue, _initialMaxValue);
}
/*
Apply the behavior of this modifier (set by VROInterpolateValues) on the given initialValue
with referenceFactor to the preset _referenceFactor.
*/
VROVector3f applyModifier(VROParticle &particle, VROVector3f initialValue) {
if (_modifierInterval.size() <= 0) {
return initialValue;
}
double deltaFactor = getReferenceFactorForParticle(particle);
return getFinalValue(initialValue, deltaFactor);
}
private:
void init(VROVector3f minRange, VROVector3f maxRange, VROModifierFactor factor) {
_initialMinValue = minRange;
_initialMaxValue = maxRange;
_referenceFactor = factor;
}
/*
Min and Max ranges from which randomize across and determine the initial value applied
by this modifier.
*/
VROVector3f _initialMinValue;
VROVector3f _initialMaxValue;
/*
Reference factor this modifier will interpolate against (Time, Distance or Velocity).
*/
VROModifierFactor _referenceFactor;
/*
List of VROModifiers with values dictating the behavior of this modifier, along which this
VROParticleModifier will interpolate against.
*/
std::vector<VROModifierInterval> _modifierInterval;
/*
Sets a list of VROModifierInterval values that will be used by this VROParticleModifier.
*/
void setInterpolatedPoints(std::vector<VROModifierInterval> values) {
if (values.size() == 0 ){
return;
}
std::sort(values.begin(), values.end());
for (int i = 0; i < values.size() - 1; i ++) {
if (values[i].endFactor > values[i + 1].startFactor
|| (values[i].startFactor > values[i].endFactor)) {
perror("Attempted to set an invalid set of interpolated points for the Particle Emitter!");
return;
}
}
_modifierInterval = values;
}
/*
Returns the referenceFactor factor value from the provided particle. The type of referenceFactor factor
is determined by this VROParticleModifier _referenceFactor.
*/
double getReferenceFactorForParticle(const VROParticle &particle) {
if (_referenceFactor == VROModifierFactor::Distance) {
return particle.distanceTraveled;
} else if (_referenceFactor == VROModifierFactor::Velocity) {
return particle.velocity;
}
return particle.timeSinceSpawnedInMs;
}
/*
With the given particle, and based on this emitter's referenceFactor factor, determine the amount of
passed time, distance, or velocity that is required to interpolate the desired value.
*/
VROVector3f getFinalValue(VROVector3f initialValue, double currentFactor) {
VROVector3f start;
VROVector3f end;
for (int i = 0; i < _modifierInterval.size(); i ++) {
// Determine if this VROModifierInterval contains a startFactor and endFactor interval
// that applies to the current deltaFactor.
if (currentFactor >= _modifierInterval[i].startFactor && currentFactor <= _modifierInterval[i].endFactor) {
// If so, calculate progression ratio
float delta = currentFactor - _modifierInterval[i].startFactor;
float deltaWindow = _modifierInterval[i].endFactor - _modifierInterval[i].startFactor;
float ratio = delta / deltaWindow;
if (i == 0){
start = initialValue;
} else {
start = _modifierInterval[i-1].targetedValue;
}
end = _modifierInterval[i].targetedValue;
return interpolatePoint(start, end, ratio);
}
// Else, if we can't find a VROModifierInterval that matches the currentFactor,
// check if the currentFactor may be referring to a time/distance period in between
// VROModifierIntervals. If so, attempt to find the last known VROModifierInterval
// that we had applied before and use its ending value.
if (i != 0 && currentFactor >= _modifierInterval[i-1].endFactor
& currentFactor <= _modifierInterval[i].endFactor) {
if (i - 1 == 0) {
start = initialValue;
} else {
start = _modifierInterval[i-2].targetedValue;
}
end = _modifierInterval[i-1].targetedValue;
return interpolatePoint(start, end, 1);
}
// Else if this is the last VROModifierInterval, and the currentFactor has progressed
// beyond it, attempt to use the ending value of the last known VROModifierInterval.
if (i == _modifierInterval.size() - 1 && currentFactor > _modifierInterval[i].endFactor) {
if (i != 0) {
start = _modifierInterval[i-1].targetedValue;
} else {
start = _modifierInterval[i].targetedValue;
}
end = _modifierInterval[i].targetedValue;
return interpolatePoint(start, end, 1);
}
}
// If no last known windows were yet found, we have yet to encounter our first
// VROModifierInterval, thus return initialValue.
return initialValue;
}
VROVector3f interpolatePoint(VROVector3f &startValue, VROVector3f &endValue, float ratio) {
VROVector3f final;
if (ratio >= 1 ) {
final = endValue;
} else {
final = startValue.interpolate(endValue, ratio);
}
return final;
}
};
#endif /* VROParticleModifier_h */