Ability to modify AC avatar blendshapes from JS

This commit is contained in:
barnold1953 2014-07-23 15:23:27 -07:00
parent f3ae228030
commit 512034fd7c
9 changed files with 125 additions and 14 deletions

View file

@ -229,11 +229,13 @@ void Agent::run() {
// setup an Avatar for the script to use
AvatarData scriptedAvatar;
// Pretend faceshift is active so we can modify facial data
scriptedAvatar.setIsFaceshiftConnected(true);
// call model URL setters with empty URLs so our avatar, if user, will have the default models
scriptedAvatar.setFaceModelURL(QUrl());
scriptedAvatar.setSkeletonModelURL(QUrl());
// give this AvatarData object to the script engine
_scriptEngine.setAvatarData(&scriptedAvatar, "Avatar");
_scriptEngine.setAvatarHashMap(&_avatarHashMap, "AvatarList");
@ -263,6 +265,7 @@ void Agent::run() {
_scriptEngine.getModelsScriptingInterface()->setModelTree(_modelViewer.getTree());
_scriptEngine.setScriptContents(scriptContents);
_scriptEngine.run();
setFinished(true);
}

View file

@ -24,11 +24,11 @@ function printVector(string, vector) {
print(string + " " + vector.x + ", " + vector.y + ", " + vector.z);
}
var CHANCE_OF_MOVING = 0.005;
var CHANCE_OF_SOUND = 0.005;
var CHANCE_OF_MOVING = 0.0;
var CHANCE_OF_SOUND = 0.0;
var CHANCE_OF_HEAD_TURNING = 0.05;
var CHANCE_OF_BIG_MOVE = 0.1;
var CHANCE_OF_WAVING = 0.009;
var CHANCE_OF_BIG_MOVE = 0.0;
var CHANCE_OF_WAVING = 0.0;
var shouldReceiveVoxels = true;
var VOXEL_FPS = 60.0;
@ -147,6 +147,13 @@ function updateBehavior(deltaTime) {
if (CHANCE_OF_MOVING == 0.000) {
Avatar.position = firstPosition;
}
//print("hi");
Avatar.setLeftBlink(1.0);
Avatar.setRightBlink(0.5);
Avatar.setBrowDownLeft(1.0);
Avatar.setMouthSize(1.0);
Avatar.setMouthSmileRight(1.0);
//print("ho");
if (shouldReceiveVoxels && ((cumulativeTime - lastVoxelQueryTime) > (1.0 / VOXEL_FPS))) {
VoxelViewer.setPosition(Avatar.position);

View file

@ -146,7 +146,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
_browAudioLift,
glm::clamp(log(_averageLoudness) / JAW_OPEN_SCALE, 0.0f, 1.0f));
}
if (!isMine) {
_faceModel.setLODDistance(static_cast<Avatar*>(_owningAvatar)->getLODDistance());
}

View file

@ -29,12 +29,18 @@ _mouthSmileRightIndex(29),
_jawOpenIndex(21) {
}
void FacialAnimationData::setBlendshapeCoefficient(int index, float val) {
_blendshapeCoefficients.resize(max((int)_blendshapeCoefficients.size(), _jawOpenIndex + 1));
if (index >= 0 && index < (int)_blendshapeCoefficients.size()) {
_blendshapeCoefficients[index] = val;
}
}
float FacialAnimationData::getBlendshapeCoefficient(int index) const {
return (index >= 0 && index < (int)_blendshapeCoefficients.size()) ? _blendshapeCoefficients[index] : 0.0f;
}
void FacialAnimationData::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp,
float jawOpen) {
void FacialAnimationData::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp, float jawOpen) {
_blendshapeCoefficients.resize(max((int)_blendshapeCoefficients.size(), _jawOpenIndex + 1));
qFill(_blendshapeCoefficients.begin(), _blendshapeCoefficients.end(), 0.0f);
_blendshapeCoefficients[_leftBlinkIndex] = leftBlink;

View file

@ -26,6 +26,23 @@ public:
FacialAnimationData();
// Setters
void setLeftBlink(float val) { setBlendshapeCoefficient(_leftBlinkIndex, val); }
void setRightBlink(float val) { setBlendshapeCoefficient(_rightBlinkIndex, val); }
void setLeftEyeOpen(float val) { setBlendshapeCoefficient(_leftBlinkIndex, val); }
void setRightEyeOpen(float val) { setBlendshapeCoefficient(_rightBlinkIndex, val); }
void setBrowDownLeft(float val) { setBlendshapeCoefficient(_browDownLeftIndex, val); }
void setBrowDownRight(float val) { setBlendshapeCoefficient(_browDownRightIndex, val); }
void setBrowUpCenter(float val) { setBlendshapeCoefficient(_browUpCenterIndex, val); }
void setBrowUpLeft(float val) { setBlendshapeCoefficient(_browUpLeftIndex, val); }
void setBrowUpRight(float val) { setBlendshapeCoefficient(_browUpRightIndex, val); }
void setMouthSize(float val) { setBlendshapeCoefficient(_jawOpenIndex, val); }
void setMouthSmileLeft(float val) { setBlendshapeCoefficient(_mouthSmileLeftIndex, val); }
void setMouthSmileRight(float val) { setBlendshapeCoefficient(_mouthSmileRightIndex, val); }
// Getters
float getLeftBlink() const { return getBlendshapeCoefficient(_leftBlinkIndex); }
float getRightBlink() const { return getBlendshapeCoefficient(_rightBlinkIndex); }
float getLeftEyeOpen() const { return getBlendshapeCoefficient(_leftEyeOpenIndex); }
@ -47,6 +64,7 @@ public:
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
private:
void setBlendshapeCoefficient(int index, float val);
float getBlendshapeCoefficient(int index) const;
int _leftBlinkIndex;

View file

@ -45,6 +45,7 @@ AvatarData::AvatarData() :
_handState(0),
_keyState(NO_KEY_DOWN),
_isChatCirclingEnabled(false),
_forceFaceshiftIsConnected(false),
_hasNewJointRotations(true),
_headData(NULL),
_handData(NULL),
@ -82,6 +83,10 @@ QByteArray AvatarData::toByteArray() {
// lazily allocate memory for HeadData in case we're not an Avatar instance
if (!_headData) {
_headData = new HeadData(this);
// In some cases, for instance for AC avatars, we might want to force faceshift to appear connected
if (_forceFaceshiftIsConnected) {
_headData->setIsFaceshiftConnected(true);
}
}
QByteArray avatarDataByteArray;

View file

@ -207,9 +207,20 @@ public:
Q_INVOKABLE virtual QStringList getJointNames() const { return _jointNames; }
// Facial Animation
Q_INVOKABLE void setLeftEyebrow(float f) {
_headData->setLeftEyebrow(f);
}
Q_INVOKABLE void setLeftBlink(float val) { _headData->setLeftBlink(val); }
Q_INVOKABLE void setRightBlink(float val) { _headData->setRightBlink(val); }
Q_INVOKABLE void setLeftEyeOpen(float val) { _headData->setLeftEyeOpen(val); }
Q_INVOKABLE void setRightEyeOpen(float val) { _headData->setRightEyeOpen(val); }
Q_INVOKABLE void setBrowDownLeft(float val) { _headData->setBrowDownLeft(val); }
Q_INVOKABLE void setBrowDownRight(float val) { _headData->setBrowDownRight(val); }
Q_INVOKABLE void setBrowUpCenter(float val) { _headData->setBrowUpCenter(val); }
Q_INVOKABLE void setBrowUpLeft(float val) { _headData->setBrowUpLeft(val); }
Q_INVOKABLE void setBrowUpRight(float val) { _headData->setBrowUpRight(val); }
Q_INVOKABLE void setMouthSize(float val) { _headData->setMouthSize(val); }
Q_INVOKABLE void setMouthSmileLeft(float val) { _headData->setMouthSmileLeft(val); }
Q_INVOKABLE void setMouthSmileRight(float val) { _headData->setMouthSmileRight(val); }
void setIsFaceshiftConnected(bool isFaceshift) { _forceFaceshiftIsConnected = isFaceshift; }
// key state
void setKeyState(KeyState s) { _keyState = s; }
@ -305,6 +316,7 @@ protected:
std::string _chatMessage;
bool _isChatCirclingEnabled;
bool _forceFaceshiftIsConnected;
bool _hasNewJointRotations; // set in AvatarData, cleared in Avatar

View file

@ -55,6 +55,55 @@ void HeadData::setOrientation(const glm::quat& orientation) {
_baseRoll = eulers.z;
}
void HeadData::setLeftBlink(float val) {
_facialAnimationData->setLeftBlink(val);
}
void HeadData::setRightBlink(float val) {
_facialAnimationData->setRightBlink(val);
}
void HeadData::setLeftEyeOpen(float val) {
_facialAnimationData->setLeftEyeOpen(val);
}
void HeadData::setRightEyeOpen(float val) {
_facialAnimationData->setRightEyeOpen(val);
}
void HeadData::setBrowDownLeft(float val) {
_facialAnimationData->setBrowDownLeft(val);
}
void HeadData::setBrowDownRight(float val) {
_facialAnimationData->setBrowDownRight(val);
}
void HeadData::setBrowUpCenter(float val) {
_facialAnimationData->setBrowUpCenter(val);
}
void HeadData::setBrowUpLeft(float val) {
_facialAnimationData->setBrowUpLeft(val);
}
void HeadData::setBrowUpRight(float val) {
_facialAnimationData->setBrowUpRight(val);
}
void HeadData::setMouthSize(float val) {
_facialAnimationData->setMouthSize(val);
}
void HeadData::setMouthSmileLeft(float val) {
_facialAnimationData->setLeftBlink(val);
}
void HeadData::setMouthSmileRight(float val) {
_facialAnimationData->setMouthSmileRight(val);
}
void HeadData::addYaw(float yaw) {
setBaseYaw(_baseYaw + yaw);
}

View file

@ -61,9 +61,20 @@ public:
void setPupilDilation(float pupilDilation) { _pupilDilation = pupilDilation; }
// Facial animation
void setLeftEyebrow(float f) {
void setLeftBlink(float val);
void setRightBlink(float val);
void setLeftEyeOpen(float val);
void setRightEyeOpen(float val);
void setBrowDownLeft(float val);
void setBrowDownRight(float val);
void setBrowUpCenter(float val);
void setBrowUpLeft(float val);
void setBrowUpRight(float val);
void setMouthSize(float val);
void setMouthSmileLeft(float val);
void setMouthSmileRight(float val);
}
void setIsFaceshiftConnected(bool isFaceshiftConnected) { _isFaceshiftConnected = isFaceshiftConnected; }
// degrees
void addYaw(float yaw);