mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
fb38fd05ed
25 changed files with 231 additions and 161 deletions
|
@ -153,11 +153,11 @@ void Agent::run() {
|
|||
|
||||
qDebug() << "Downloaded script:" << scriptContents;
|
||||
|
||||
_scriptEngine = new ScriptEngine(scriptContents, _payload);
|
||||
_scriptEngine = std::unique_ptr<ScriptEngine>(new ScriptEngine(scriptContents, _payload));
|
||||
_scriptEngine->setParent(this); // be the parent of the script engine so it gets moved when we do
|
||||
|
||||
// setup an Avatar for the script to use
|
||||
ScriptableAvatar scriptedAvatar(_scriptEngine);
|
||||
ScriptableAvatar scriptedAvatar(_scriptEngine.get());
|
||||
scriptedAvatar.setForceFaceTrackerConnected(true);
|
||||
|
||||
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
||||
|
@ -191,22 +191,21 @@ void Agent::run() {
|
|||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
|
||||
_scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
||||
|
||||
// we need to make sure that init has been called for our EntityScriptingInterface
|
||||
// so that it actually has a jurisdiction listener when we ask it for it next
|
||||
entityScriptingInterface->init();
|
||||
_entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener());
|
||||
|
||||
_entityViewer.init();
|
||||
|
||||
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
||||
|
||||
// wire up our additional agent related processing to the update signal
|
||||
QObject::connect(_scriptEngine, &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio);
|
||||
QObject::connect(_scriptEngine.get(), &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio);
|
||||
|
||||
_scriptEngine->run();
|
||||
setFinished(true);
|
||||
|
||||
// kill the avatar identity timer
|
||||
delete _avatarIdentityTimer;
|
||||
|
||||
// delete the script engine
|
||||
delete _scriptEngine;
|
||||
|
||||
}
|
||||
|
||||
void Agent::setIsAvatar(bool isAvatar) {
|
||||
|
@ -227,10 +226,17 @@ void Agent::setIsAvatar(bool isAvatar) {
|
|||
}
|
||||
|
||||
if (!_isAvatar) {
|
||||
delete _avatarIdentityTimer;
|
||||
_avatarIdentityTimer = NULL;
|
||||
delete _avatarBillboardTimer;
|
||||
_avatarBillboardTimer = NULL;
|
||||
if (_avatarIdentityTimer) {
|
||||
_avatarIdentityTimer->stop();
|
||||
delete _avatarIdentityTimer;
|
||||
_avatarIdentityTimer = nullptr;
|
||||
}
|
||||
|
||||
if (_avatarBillboardTimer) {
|
||||
_avatarIdentityTimer->stop();
|
||||
delete _avatarIdentityTimer;
|
||||
_avatarBillboardTimer = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef hifi_Agent_h
|
||||
#define hifi_Agent_h
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
@ -61,7 +62,7 @@ private slots:
|
|||
void processAgentAvatarAndAudio(float deltaTime);
|
||||
|
||||
private:
|
||||
ScriptEngine* _scriptEngine;
|
||||
std::unique_ptr<ScriptEngine> _scriptEngine;
|
||||
EntityEditPacketSender _entityEditSender;
|
||||
EntityTreeHeadlessViewer _entityViewer;
|
||||
QTimer* _pingTimer;
|
||||
|
|
|
@ -4347,6 +4347,8 @@ void Application::stopScript(const QString &scriptName, bool restart) {
|
|||
}
|
||||
|
||||
void Application::reloadAllScripts() {
|
||||
DependencyManager::get<ScriptCache>()->clearCache();
|
||||
getEntities()->reloadEntityScripts();
|
||||
stopAllScripts(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -1302,7 +1302,7 @@ void MyAvatar::initAnimGraph() {
|
|||
// or run a local web-server
|
||||
// python -m SimpleHTTPServer&
|
||||
//auto graphUrl = QUrl("http://localhost:8000/avatar.json");
|
||||
auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/04a02c47eb56d8bfaebb/raw/5f2a4e268d35147c83d44881e268f83a6296e89b/ik-avatar-hands.json");
|
||||
auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/04a02c47eb56d8bfaebb/raw/72517b231f606b724c5169e02642e401f9af5a54/ik-avatar-hands.json");
|
||||
_rig->initAnimGraph(graphUrl, _skeletonModel.getGeometry()->getFBXGeometry());
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "AnimInverseKinematics.h"
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
@ -54,7 +55,20 @@ void AnimInverseKinematics::computeAbsolutePoses(AnimPoseVec& absolutePoses) con
|
|||
|
||||
void AnimInverseKinematics::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar) {
|
||||
// if there are dups, last one wins.
|
||||
_targetVarVec.push_back(IKTargetVar(jointName, positionVar.toStdString(), rotationVar.toStdString()));
|
||||
bool found = false;
|
||||
for (auto& targetVar: _targetVarVec) {
|
||||
if (targetVar.jointName == jointName) {
|
||||
// update existing targetVar
|
||||
targetVar.positionVar = positionVar.toStdString();
|
||||
targetVar.rotationVar = rotationVar.toStdString();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// create a new entry
|
||||
_targetVarVec.push_back(IKTargetVar(jointName, positionVar.toStdString(), rotationVar.toStdString()));
|
||||
}
|
||||
}
|
||||
|
||||
static int findRootJointInSkeleton(AnimSkeleton::ConstPointer skeleton, int index) {
|
||||
|
@ -68,6 +82,12 @@ static int findRootJointInSkeleton(AnimSkeleton::ConstPointer skeleton, int inde
|
|||
return rootIndex;
|
||||
}
|
||||
|
||||
struct IKTarget {
|
||||
AnimPose pose;
|
||||
int index;
|
||||
int rootIndex;
|
||||
};
|
||||
|
||||
//virtual
|
||||
const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVars, float dt, AnimNode::Triggers& triggersOut) {
|
||||
|
||||
|
@ -76,43 +96,53 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
|||
return _relativePoses;
|
||||
}
|
||||
|
||||
// evaluate target vars
|
||||
// build a list of targets from _targetVarVec
|
||||
std::vector<IKTarget> targets;
|
||||
bool removeUnfoundJoints = false;
|
||||
for (auto& targetVar : _targetVarVec) {
|
||||
|
||||
// lazy look up of jointIndices and insertion into _absoluteTargets map
|
||||
if (!targetVar.hasPerformedJointLookup) {
|
||||
targetVar.jointIndex = _skeleton->nameToJointIndex(targetVar.jointName);
|
||||
if (targetVar.jointIndex >= 0) {
|
||||
// insert into _absoluteTargets map
|
||||
IKTarget target;
|
||||
target.pose = AnimPose::identity;
|
||||
target.rootIndex = findRootJointInSkeleton(_skeleton, targetVar.jointIndex);
|
||||
_absoluteTargets[targetVar.jointIndex] = target;
|
||||
|
||||
if (targetVar.jointIndex > _maxTargetIndex) {
|
||||
_maxTargetIndex = targetVar.jointIndex;
|
||||
}
|
||||
if (targetVar.jointIndex == -1) {
|
||||
// this targetVar hasn't been validated yet...
|
||||
int jointIndex = _skeleton->nameToJointIndex(targetVar.jointName);
|
||||
if (jointIndex >= 0) {
|
||||
// this targetVar has a valid joint --> cache the indices
|
||||
targetVar.jointIndex = jointIndex;
|
||||
targetVar.rootIndex = findRootJointInSkeleton(_skeleton, jointIndex);
|
||||
} else {
|
||||
qCWarning(animation) << "AnimInverseKinematics could not find jointName" << targetVar.jointName << "in skeleton";
|
||||
removeUnfoundJoints = true;
|
||||
}
|
||||
targetVar.hasPerformedJointLookup = true;
|
||||
}
|
||||
|
||||
if (targetVar.jointIndex >= 0) {
|
||||
// update pose in _absoluteTargets map
|
||||
auto iter = _absoluteTargets.find(targetVar.jointIndex);
|
||||
if (iter != _absoluteTargets.end()) {
|
||||
} else {
|
||||
// TODO: get this done without a double-lookup of each var in animVars
|
||||
if (animVars.hasKey(targetVar.positionVar) || animVars.hasKey(targetVar.rotationVar)) {
|
||||
IKTarget target;
|
||||
AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, _relativePoses);
|
||||
iter->second.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans);
|
||||
iter->second.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot);
|
||||
target.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans);
|
||||
target.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot);
|
||||
target.rootIndex = targetVar.rootIndex;
|
||||
target.index = targetVar.jointIndex;
|
||||
targets.push_back(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RELAX! Don't do it.
|
||||
// relaxTowardDefaults(dt);
|
||||
if (removeUnfoundJoints) {
|
||||
int numVars = _targetVarVec.size();
|
||||
int i = 0;
|
||||
while (i < numVars) {
|
||||
if (_targetVarVec[i].jointIndex == -1) {
|
||||
if (numVars > 1) {
|
||||
// swap i for last element
|
||||
_targetVarVec[i] = _targetVarVec[numVars - 1];
|
||||
}
|
||||
_targetVarVec.pop_back();
|
||||
--numVars;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_absoluteTargets.empty()) {
|
||||
if (targets.empty()) {
|
||||
// no IK targets but still need to enforce constraints
|
||||
std::map<int, RotationConstraint*>::iterator constraintItr = _constraints.begin();
|
||||
while (constraintItr != _constraints.end()) {
|
||||
|
@ -135,11 +165,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
|||
quint64 expiry = usecTimestampNow() + MAX_IK_TIME;
|
||||
do {
|
||||
largestError = 0.0f;
|
||||
for (auto& targetPair: _absoluteTargets) {
|
||||
for (auto& target: targets) {
|
||||
int lowestMovedIndex = _relativePoses.size() - 1;
|
||||
int tipIndex = targetPair.first;
|
||||
AnimPose targetPose = targetPair.second.pose;
|
||||
int rootIndex = targetPair.second.rootIndex;
|
||||
int tipIndex = target.index;
|
||||
AnimPose targetPose = target.pose;
|
||||
int rootIndex = target.rootIndex;
|
||||
if (rootIndex != -1) {
|
||||
// transform targetPose into skeleton's absolute frame
|
||||
AnimPose& rootPose = _relativePoses[rootIndex];
|
||||
|
@ -150,11 +180,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
|||
glm::vec3 tip = absolutePoses[tipIndex].trans;
|
||||
float error = glm::length(targetPose.trans - tip);
|
||||
|
||||
// descend toward root, rotating each joint to get tip closer to target
|
||||
int index = _skeleton->getParentIndex(tipIndex);
|
||||
while (index != -1 && error > ACCEPTABLE_RELATIVE_ERROR) {
|
||||
// descend toward root, pivoting each joint to get tip closer to target
|
||||
int pivotIndex = _skeleton->getParentIndex(tipIndex);
|
||||
while (pivotIndex != -1 && error > ACCEPTABLE_RELATIVE_ERROR) {
|
||||
// compute the two lines that should be aligned
|
||||
glm::vec3 jointPosition = absolutePoses[index].trans;
|
||||
glm::vec3 jointPosition = absolutePoses[pivotIndex].trans;
|
||||
glm::vec3 leverArm = tip - jointPosition;
|
||||
glm::vec3 targetLine = targetPose.trans - jointPosition;
|
||||
|
||||
|
@ -173,29 +203,34 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
|||
angle = 0.5f * angle;
|
||||
glm::quat deltaRotation = glm::angleAxis(angle, axis);
|
||||
|
||||
int parentIndex = _skeleton->getParentIndex(index);
|
||||
int parentIndex = _skeleton->getParentIndex(pivotIndex);
|
||||
if (parentIndex == -1) {
|
||||
// TODO? apply constraints to root?
|
||||
// TODO? harvest the root's transform as movement of entire skeleton?
|
||||
} else {
|
||||
// compute joint's new parent-relative rotation
|
||||
// Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q
|
||||
glm::quat newRot = glm::normalize(glm::inverse(absolutePoses[parentIndex].rot) * deltaRotation * absolutePoses[index].rot);
|
||||
RotationConstraint* constraint = getConstraint(index);
|
||||
glm::quat newRot = glm::normalize(glm::inverse(
|
||||
absolutePoses[parentIndex].rot) *
|
||||
deltaRotation *
|
||||
absolutePoses[pivotIndex].rot);
|
||||
RotationConstraint* constraint = getConstraint(pivotIndex);
|
||||
if (constraint) {
|
||||
bool constrained = constraint->apply(newRot);
|
||||
if (constrained) {
|
||||
// the constraint will modify the movement of the tip so we have to compute the modified
|
||||
// model-frame deltaRotation
|
||||
// Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^
|
||||
deltaRotation = absolutePoses[parentIndex].rot * newRot * glm::inverse(absolutePoses[index].rot);
|
||||
deltaRotation = absolutePoses[parentIndex].rot *
|
||||
newRot *
|
||||
glm::inverse(absolutePoses[pivotIndex].rot);
|
||||
}
|
||||
}
|
||||
_relativePoses[index].rot = newRot;
|
||||
_relativePoses[pivotIndex].rot = newRot;
|
||||
}
|
||||
// this joint has been changed so we check to see if it has the lowest index
|
||||
if (index < lowestMovedIndex) {
|
||||
lowestMovedIndex = index;
|
||||
if (pivotIndex < lowestMovedIndex) {
|
||||
lowestMovedIndex = pivotIndex;
|
||||
}
|
||||
|
||||
// keep track of tip's new position as we descend towards root
|
||||
|
@ -203,7 +238,7 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
|||
error = glm::length(targetPose.trans - tip);
|
||||
}
|
||||
}
|
||||
index = _skeleton->getParentIndex(index);
|
||||
pivotIndex = _skeleton->getParentIndex(pivotIndex);
|
||||
}
|
||||
if (largestError < error) {
|
||||
largestError = error;
|
||||
|
@ -248,12 +283,16 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
loadPoses(underPoses);
|
||||
} else {
|
||||
// relax toward underpose
|
||||
const float RELAXATION_TIMESCALE = 0.125f;
|
||||
const float alpha = glm::clamp(dt / RELAXATION_TIMESCALE, 0.0f, 1.0f);
|
||||
// HACK: this relaxation needs to be constant per-frame rather than per-realtime
|
||||
// in order to prevent IK "flutter" for bad FPS. The bad news is that the good parts
|
||||
// of this relaxation will be FPS dependent (low FPS will make the limbs align slower
|
||||
// in real-time), however most people will not notice this and this problem is less
|
||||
// annoying than the flutter.
|
||||
const float blend = (1.0f / 60.0f) / (0.25f); // effectively: dt / RELAXATION_TIMESCALE
|
||||
int numJoints = (int)_relativePoses.size();
|
||||
for (int i = 0; i < numJoints; ++i) {
|
||||
float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot, underPoses[i].rot));
|
||||
_relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * underPoses[i].rot, alpha));
|
||||
_relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * underPoses[i].rot, blend));
|
||||
}
|
||||
}
|
||||
return evaluate(animVars, dt, triggersOut);
|
||||
|
@ -277,10 +316,6 @@ void AnimInverseKinematics::clearConstraints() {
|
|||
_constraints.clear();
|
||||
}
|
||||
|
||||
const glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
|
||||
const glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
|
||||
const glm::vec3 zAxis(0.0f, 0.0f, 1.0f);
|
||||
|
||||
void AnimInverseKinematics::initConstraints() {
|
||||
if (!_skeleton) {
|
||||
return;
|
||||
|
@ -288,7 +323,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
// We create constraints for the joints shown here
|
||||
// (and their Left counterparts if applicable).
|
||||
//
|
||||
//
|
||||
//
|
||||
// O RightHand
|
||||
// Head /
|
||||
// O /
|
||||
|
@ -306,7 +341,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
// y |
|
||||
// | |
|
||||
// | O---O---O RightUpLeg
|
||||
// z | | |
|
||||
// z | | Hips2 |
|
||||
// \ | | |
|
||||
// \| | |
|
||||
// x -----+ O O RightLeg
|
||||
|
@ -334,7 +369,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
|
||||
_constraints.clear();
|
||||
for (int i = 0; i < numJoints; ++i) {
|
||||
// compute the joint's baseName and remember if it was Left or not
|
||||
// compute the joint's baseName and remember whether its prefix was "Left" or not
|
||||
QString baseName = _skeleton->getJointName(i);
|
||||
bool isLeft = baseName.startsWith("Left", Qt::CaseInsensitive);
|
||||
float mirror = isLeft ? -1.0f : 1.0f;
|
||||
|
@ -442,7 +477,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
const float MAX_HAND_SWING = PI / 2.0f;
|
||||
minDots.push_back(cosf(MAX_HAND_SWING));
|
||||
stConstraint->setSwingLimits(minDots);
|
||||
|
||||
|
||||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (baseName.startsWith("Shoulder", Qt::CaseInsensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
|
@ -467,6 +502,18 @@ void AnimInverseKinematics::initConstraints() {
|
|||
minDots.push_back(cosf(MAX_SPINE_SWING));
|
||||
stConstraint->setSwingLimits(minDots);
|
||||
|
||||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (baseName.startsWith("Hips2", Qt::CaseInsensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
const float MAX_SPINE_TWIST = PI / 8.0f;
|
||||
stConstraint->setTwistLimits(-MAX_SPINE_TWIST, MAX_SPINE_TWIST);
|
||||
|
||||
std::vector<float> minDots;
|
||||
const float MAX_SPINE_SWING = PI / 14.0f;
|
||||
minDots.push_back(cosf(MAX_SPINE_SWING));
|
||||
stConstraint->setSwingLimits(minDots);
|
||||
|
||||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (0 == baseName.compare("Neck", Qt::CaseInsensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
|
@ -488,18 +535,18 @@ void AnimInverseKinematics::initConstraints() {
|
|||
|
||||
// we determine the max/min angles by rotating the swing limit lines from parent- to child-frame
|
||||
// then measure the angles to swing the yAxis into alignment
|
||||
glm::vec3 hingeAxis = - mirror * zAxis;
|
||||
glm::vec3 hingeAxis = - mirror * Vectors::UNIT_Z;
|
||||
const float MIN_ELBOW_ANGLE = 0.05f;
|
||||
const float MAX_ELBOW_ANGLE = 11.0f * PI / 12.0f;
|
||||
glm::quat invReferenceRotation = glm::inverse(referenceRotation);
|
||||
glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_ELBOW_ANGLE, hingeAxis) * yAxis;
|
||||
glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_ELBOW_ANGLE, hingeAxis) * yAxis;
|
||||
glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_ELBOW_ANGLE, hingeAxis) * Vectors::UNIT_Y;
|
||||
glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_ELBOW_ANGLE, hingeAxis) * Vectors::UNIT_Y;
|
||||
|
||||
// for the rest of the math we rotate hingeAxis into the child frame
|
||||
hingeAxis = referenceRotation * hingeAxis;
|
||||
eConstraint->setHingeAxis(hingeAxis);
|
||||
|
||||
glm::vec3 projectedYAxis = glm::normalize(yAxis - glm::dot(yAxis, hingeAxis) * hingeAxis);
|
||||
glm::vec3 projectedYAxis = glm::normalize(Vectors::UNIT_Y - glm::dot(Vectors::UNIT_Y, hingeAxis) * hingeAxis);
|
||||
float minAngle = acosf(glm::dot(projectedYAxis, minSwingAxis));
|
||||
if (glm::dot(hingeAxis, glm::cross(projectedYAxis, minSwingAxis)) < 0.0f) {
|
||||
minAngle = - minAngle;
|
||||
|
@ -516,21 +563,21 @@ void AnimInverseKinematics::initConstraints() {
|
|||
ElbowConstraint* eConstraint = new ElbowConstraint();
|
||||
glm::quat referenceRotation = _defaultRelativePoses[i].rot;
|
||||
eConstraint->setReferenceRotation(referenceRotation);
|
||||
glm::vec3 hingeAxis = -1.0f * xAxis;
|
||||
glm::vec3 hingeAxis = -1.0f * Vectors::UNIT_X;
|
||||
|
||||
// we determine the max/min angles by rotating the swing limit lines from parent- to child-frame
|
||||
// then measure the angles to swing the yAxis into alignment
|
||||
const float MIN_KNEE_ANGLE = 0.0f;
|
||||
const float MAX_KNEE_ANGLE = 3.0f * PI / 4.0f;
|
||||
glm::quat invReferenceRotation = glm::inverse(referenceRotation);
|
||||
glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_KNEE_ANGLE, hingeAxis) * yAxis;
|
||||
glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_KNEE_ANGLE, hingeAxis) * yAxis;
|
||||
glm::vec3 minSwingAxis = invReferenceRotation * glm::angleAxis(MIN_KNEE_ANGLE, hingeAxis) * Vectors::UNIT_Y;
|
||||
glm::vec3 maxSwingAxis = invReferenceRotation * glm::angleAxis(MAX_KNEE_ANGLE, hingeAxis) * Vectors::UNIT_Y;
|
||||
|
||||
// for the rest of the math we rotate hingeAxis into the child frame
|
||||
hingeAxis = referenceRotation * hingeAxis;
|
||||
eConstraint->setHingeAxis(hingeAxis);
|
||||
|
||||
glm::vec3 projectedYAxis = glm::normalize(yAxis - glm::dot(yAxis, hingeAxis) * hingeAxis);
|
||||
glm::vec3 projectedYAxis = glm::normalize(Vectors::UNIT_Y - glm::dot(Vectors::UNIT_Y, hingeAxis) * hingeAxis);
|
||||
float minAngle = acosf(glm::dot(projectedYAxis, minSwingAxis));
|
||||
if (glm::dot(hingeAxis, glm::cross(projectedYAxis, minSwingAxis)) < 0.0f) {
|
||||
minAngle = - minAngle;
|
||||
|
@ -550,8 +597,8 @@ void AnimInverseKinematics::initConstraints() {
|
|||
// these directions are approximate swing limits in parent-frame
|
||||
// NOTE: they don't need to be normalized
|
||||
std::vector<glm::vec3> swungDirections;
|
||||
swungDirections.push_back(yAxis);
|
||||
swungDirections.push_back(xAxis);
|
||||
swungDirections.push_back(Vectors::UNIT_Y);
|
||||
swungDirections.push_back(Vectors::UNIT_X);
|
||||
swungDirections.push_back(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
swungDirections.push_back(glm::vec3(1.0f, 1.0f, -1.0f));
|
||||
|
||||
|
@ -575,13 +622,10 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele
|
|||
AnimNode::setSkeletonInternal(skeleton);
|
||||
|
||||
// invalidate all targetVars
|
||||
for (auto& targetVar : _targetVarVec) {
|
||||
targetVar.hasPerformedJointLookup = false;
|
||||
for (auto& targetVar: _targetVarVec) {
|
||||
targetVar.jointIndex = -1;
|
||||
}
|
||||
|
||||
// invalidate all targets
|
||||
_absoluteTargets.clear();
|
||||
|
||||
_maxTargetIndex = 0;
|
||||
|
||||
if (skeleton) {
|
||||
|
|
|
@ -50,23 +50,17 @@ protected:
|
|||
rotationVar(rotationVarIn),
|
||||
jointName(jointNameIn),
|
||||
jointIndex(-1),
|
||||
hasPerformedJointLookup(false) {}
|
||||
rootIndex(-1) {}
|
||||
|
||||
std::string positionVar;
|
||||
std::string rotationVar;
|
||||
QString jointName;
|
||||
int jointIndex; // cached joint index
|
||||
bool hasPerformedJointLookup = false;
|
||||
};
|
||||
|
||||
struct IKTarget {
|
||||
AnimPose pose;
|
||||
int rootIndex;
|
||||
int rootIndex; // cached root index
|
||||
};
|
||||
|
||||
std::map<int, RotationConstraint*> _constraints;
|
||||
std::vector<IKTargetVar> _targetVarVec;
|
||||
std::map<int, IKTarget> _absoluteTargets; // IK targets of end-points
|
||||
AnimPoseVec _defaultRelativePoses; // poses of the relaxed state
|
||||
AnimPoseVec _relativePoses; // current relative poses
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// AnimController.cpp
|
||||
// AnimManipulator.cpp
|
||||
//
|
||||
// Created by Anthony J. Thibault on 9/8/15.
|
||||
// Copyright (c) 2015 High Fidelity, Inc. All rights reserved.
|
||||
|
@ -8,24 +8,25 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "AnimController.h"
|
||||
#include "AnimManipulator.h"
|
||||
#include "AnimUtil.h"
|
||||
#include "AnimationLogging.h"
|
||||
|
||||
AnimController::AnimController(const std::string& id, float alpha) :
|
||||
AnimNode(AnimNode::Type::Controller, id),
|
||||
AnimManipulator::AnimManipulator(const std::string& id, float alpha) :
|
||||
AnimNode(AnimNode::Type::Manipulator, id),
|
||||
_alpha(alpha) {
|
||||
|
||||
}
|
||||
|
||||
AnimController::~AnimController() {
|
||||
AnimManipulator::~AnimManipulator() {
|
||||
|
||||
}
|
||||
|
||||
const AnimPoseVec& AnimController::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
|
||||
const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) {
|
||||
return overlay(animVars, dt, triggersOut, _skeleton->getRelativeBindPoses());
|
||||
}
|
||||
|
||||
const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
|
||||
const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
|
||||
_alpha = animVars.lookup(_alphaVar, _alpha);
|
||||
|
||||
for (auto& jointVar : _jointVars) {
|
||||
|
@ -33,52 +34,56 @@ const AnimPoseVec& AnimController::overlay(const AnimVariantMap& animVars, float
|
|||
QString qJointName = QString::fromStdString(jointVar.jointName);
|
||||
jointVar.jointIndex = _skeleton->nameToJointIndex(qJointName);
|
||||
if (jointVar.jointIndex < 0) {
|
||||
qCWarning(animation) << "AnimController could not find jointName" << qJointName << "in skeleton";
|
||||
qCWarning(animation) << "AnimManipulator could not find jointName" << qJointName << "in skeleton";
|
||||
}
|
||||
jointVar.hasPerformedJointLookup = true;
|
||||
}
|
||||
|
||||
if (jointVar.jointIndex >= 0) {
|
||||
|
||||
AnimPose defaultPose;
|
||||
glm::quat absRot;
|
||||
glm::quat parentAbsRot;
|
||||
AnimPose defaultAbsPose;
|
||||
AnimPose defaultRelPose;
|
||||
AnimPose parentAbsPose = AnimPose::identity;
|
||||
if (jointVar.jointIndex <= (int)underPoses.size()) {
|
||||
|
||||
// jointVar is an absolute rotation, if it is not set we will use the underPose as our default value
|
||||
defaultPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses);
|
||||
absRot = animVars.lookup(jointVar.var, defaultPose.rot);
|
||||
defaultRelPose = underPoses[jointVar.jointIndex];
|
||||
defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses);
|
||||
defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot);
|
||||
|
||||
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose.
|
||||
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
|
||||
if (parentIndex >= 0) {
|
||||
parentAbsRot = _skeleton->getAbsolutePose(parentIndex, underPoses).rot;
|
||||
parentAbsPose = _skeleton->getAbsolutePose(parentIndex, underPoses);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// jointVar is an absolute rotation, if it is not set we will use the bindPose as our default value
|
||||
defaultPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex);
|
||||
absRot = animVars.lookup(jointVar.var, defaultPose.rot);
|
||||
defaultRelPose = AnimPose::identity;
|
||||
defaultAbsPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex);
|
||||
defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot);
|
||||
|
||||
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose
|
||||
// here we use the bind pose
|
||||
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
|
||||
if (parentIndex >= 0) {
|
||||
parentAbsRot = _skeleton->getAbsoluteBindPose(parentIndex).rot;
|
||||
parentAbsPose = _skeleton->getAbsoluteBindPose(parentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// convert from absolute to relative
|
||||
glm::quat relRot = glm::inverse(parentAbsRot) * absRot;
|
||||
_poses[jointVar.jointIndex] = AnimPose(defaultPose.scale, relRot, defaultPose.trans);
|
||||
AnimPose relPose = parentAbsPose.inverse() * defaultAbsPose;
|
||||
|
||||
// blend with underPose
|
||||
::blend(1, &defaultRelPose, &relPose, _alpha, &_poses[jointVar.jointIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
return _poses;
|
||||
}
|
||||
|
||||
void AnimController::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) {
|
||||
void AnimManipulator::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) {
|
||||
AnimNode::setSkeletonInternal(skeleton);
|
||||
|
||||
// invalidate all jointVar indices
|
||||
|
@ -97,10 +102,10 @@ void AnimController::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) {
|
|||
}
|
||||
|
||||
// for AnimDebugDraw rendering
|
||||
const AnimPoseVec& AnimController::getPosesInternal() const {
|
||||
const AnimPoseVec& AnimManipulator::getPosesInternal() const {
|
||||
return _poses;
|
||||
}
|
||||
|
||||
void AnimController::addJointVar(const JointVar& jointVar) {
|
||||
void AnimManipulator::addJointVar(const JointVar& jointVar) {
|
||||
_jointVars.push_back(jointVar);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// AnimController.h
|
||||
// AnimManipulator.h
|
||||
//
|
||||
// Created by Anthony J. Thibault on 9/8/15.
|
||||
// Copyright (c) 2015 High Fidelity, Inc. All rights reserved.
|
||||
|
@ -8,19 +8,19 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_AnimController_h
|
||||
#define hifi_AnimController_h
|
||||
#ifndef hifi_AnimManipulator_h
|
||||
#define hifi_AnimManipulator_h
|
||||
|
||||
#include "AnimNode.h"
|
||||
|
||||
// Allows procedural control over a set of joints.
|
||||
|
||||
class AnimController : public AnimNode {
|
||||
class AnimManipulator : public AnimNode {
|
||||
public:
|
||||
friend class AnimTests;
|
||||
|
||||
AnimController(const std::string& id, float alpha);
|
||||
virtual ~AnimController() override;
|
||||
AnimManipulator(const std::string& id, float alpha);
|
||||
virtual ~AnimManipulator() override;
|
||||
|
||||
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, Triggers& triggersOut) override;
|
||||
virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override;
|
||||
|
@ -50,9 +50,9 @@ protected:
|
|||
std::vector<JointVar> _jointVars;
|
||||
|
||||
// no copies
|
||||
AnimController(const AnimController&) = delete;
|
||||
AnimController& operator=(const AnimController&) = delete;
|
||||
AnimManipulator(const AnimManipulator&) = delete;
|
||||
AnimManipulator& operator=(const AnimManipulator&) = delete;
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_AnimController_h
|
||||
#endif // hifi_AnimManipulator_h
|
|
@ -40,7 +40,7 @@ public:
|
|||
BlendLinear,
|
||||
Overlay,
|
||||
StateMachine,
|
||||
Controller,
|
||||
Manipulator,
|
||||
InverseKinematics,
|
||||
NumTypes
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "AnimOverlay.h"
|
||||
#include "AnimNodeLoader.h"
|
||||
#include "AnimStateMachine.h"
|
||||
#include "AnimController.h"
|
||||
#include "AnimManipulator.h"
|
||||
#include "AnimInverseKinematics.h"
|
||||
|
||||
using NodeLoaderFunc = AnimNode::Pointer (*)(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
|
@ -31,7 +31,7 @@ static AnimNode::Pointer loadClipNode(const QJsonObject& jsonObj, const QString&
|
|||
static AnimNode::Pointer loadBlendLinearNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
static AnimNode::Pointer loadOverlayNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
static AnimNode::Pointer loadStateMachineNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
static AnimNode::Pointer loadControllerNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
static AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
|
||||
// called after children have been loaded
|
||||
|
@ -40,7 +40,7 @@ static bool processClipNode(AnimNode::Pointer node, const QJsonObject& jsonObj,
|
|||
static bool processBlendLinearNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; }
|
||||
static bool processOverlayNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; }
|
||||
bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
|
||||
static bool processControllerNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; }
|
||||
static bool processManipulatorNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; }
|
||||
static bool processInverseKinematicsNode(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { return true; }
|
||||
|
||||
static const char* animNodeTypeToString(AnimNode::Type type) {
|
||||
|
@ -49,7 +49,7 @@ static const char* animNodeTypeToString(AnimNode::Type type) {
|
|||
case AnimNode::Type::BlendLinear: return "blendLinear";
|
||||
case AnimNode::Type::Overlay: return "overlay";
|
||||
case AnimNode::Type::StateMachine: return "stateMachine";
|
||||
case AnimNode::Type::Controller: return "controller";
|
||||
case AnimNode::Type::Manipulator: return "manipulator";
|
||||
case AnimNode::Type::InverseKinematics: return "inverseKinematics";
|
||||
case AnimNode::Type::NumTypes: return nullptr;
|
||||
};
|
||||
|
@ -62,7 +62,7 @@ static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) {
|
|||
case AnimNode::Type::BlendLinear: return loadBlendLinearNode;
|
||||
case AnimNode::Type::Overlay: return loadOverlayNode;
|
||||
case AnimNode::Type::StateMachine: return loadStateMachineNode;
|
||||
case AnimNode::Type::Controller: return loadControllerNode;
|
||||
case AnimNode::Type::Manipulator: return loadManipulatorNode;
|
||||
case AnimNode::Type::InverseKinematics: return loadInverseKinematicsNode;
|
||||
case AnimNode::Type::NumTypes: return nullptr;
|
||||
};
|
||||
|
@ -75,7 +75,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) {
|
|||
case AnimNode::Type::BlendLinear: return processBlendLinearNode;
|
||||
case AnimNode::Type::Overlay: return processOverlayNode;
|
||||
case AnimNode::Type::StateMachine: return processStateMachineNode;
|
||||
case AnimNode::Type::Controller: return processControllerNode;
|
||||
case AnimNode::Type::Manipulator: return processManipulatorNode;
|
||||
case AnimNode::Type::InverseKinematics: return processInverseKinematicsNode;
|
||||
case AnimNode::Type::NumTypes: return nullptr;
|
||||
};
|
||||
|
@ -122,7 +122,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) {
|
|||
static AnimNode::Type stringToEnum(const QString& str) {
|
||||
// O(n), move to map when number of types becomes large.
|
||||
const int NUM_TYPES = static_cast<int>(AnimNode::Type::NumTypes);
|
||||
for (int i = 0; i < NUM_TYPES; i++ ) {
|
||||
for (int i = 0; i < NUM_TYPES; i++) {
|
||||
AnimNode::Type type = static_cast<AnimNode::Type>(i);
|
||||
if (str == animNodeTypeToString(type)) {
|
||||
return type;
|
||||
|
@ -288,10 +288,10 @@ static AnimNode::Pointer loadStateMachineNode(const QJsonObject& jsonObj, const
|
|||
return node;
|
||||
}
|
||||
|
||||
static AnimNode::Pointer loadControllerNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) {
|
||||
static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) {
|
||||
|
||||
READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr);
|
||||
auto node = std::make_shared<AnimController>(id.toStdString(), alpha);
|
||||
auto node = std::make_shared<AnimManipulator>(id.toStdString(), alpha);
|
||||
|
||||
READ_OPTIONAL_STRING(alphaVar, jsonObj);
|
||||
if (!alphaVar.isEmpty()) {
|
||||
|
@ -315,7 +315,7 @@ static AnimNode::Pointer loadControllerNode(const QJsonObject& jsonObj, const QS
|
|||
READ_STRING(var, jointObj, id, jsonUrl, nullptr);
|
||||
READ_STRING(jointName, jointObj, id, jsonUrl, nullptr);
|
||||
|
||||
AnimController::JointVar jointVar(var.toStdString(), jointName.toStdString());
|
||||
AnimManipulator::JointVar jointVar(var.toStdString(), jointName.toStdString());
|
||||
node->addJointVar(jointVar);
|
||||
};
|
||||
|
||||
|
|
|
@ -173,8 +173,8 @@ void AnimOverlay::buildEmptyBoneSet() {
|
|||
void AnimOverlay::buildLeftHandBoneSet() {
|
||||
assert(_skeleton);
|
||||
buildEmptyBoneSet();
|
||||
int headJoint = _skeleton->nameToJointIndex("LeftHand");
|
||||
for_each_child_joint(_skeleton, headJoint, [&](int i) {
|
||||
int handJoint = _skeleton->nameToJointIndex("LeftHand");
|
||||
for_each_child_joint(_skeleton, handJoint, [&](int i) {
|
||||
_boneSetVec[i] = 1.0f;
|
||||
});
|
||||
}
|
||||
|
@ -182,8 +182,8 @@ void AnimOverlay::buildLeftHandBoneSet() {
|
|||
void AnimOverlay::buildRightHandBoneSet() {
|
||||
assert(_skeleton);
|
||||
buildEmptyBoneSet();
|
||||
int headJoint = _skeleton->nameToJointIndex("RightHand");
|
||||
for_each_child_joint(_skeleton, headJoint, [&](int i) {
|
||||
int handJoint = _skeleton->nameToJointIndex("RightHand");
|
||||
for_each_child_joint(_skeleton, handJoint, [&](int i) {
|
||||
_boneSetVec[i] = 1.0f;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -154,6 +154,8 @@ public:
|
|||
void setTrigger(const std::string& key) { _triggers.insert(key); }
|
||||
void clearTriggers() { _triggers.clear(); }
|
||||
|
||||
bool hasKey(const std::string& key) const { return _map.find(key) != _map.end(); }
|
||||
|
||||
protected:
|
||||
std::map<std::string, AnimVariant> _map;
|
||||
std::set<std::string> _triggers;
|
||||
|
|
|
@ -742,12 +742,10 @@ void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::q
|
|||
|
||||
if (_enableAnimGraph && _animSkeleton) {
|
||||
if (endIndex == _leftHandJointIndex) {
|
||||
auto rootTrans = _animSkeleton->getAbsoluteBindPose(_rootJointIndex).trans;
|
||||
_animVars.set("leftHandPosition", targetPosition + rootTrans);
|
||||
_animVars.set("leftHandPosition", targetPosition);
|
||||
_animVars.set("leftHandRotation", targetRotation);
|
||||
} else if (endIndex == _rightHandJointIndex) {
|
||||
auto rootTrans = _animSkeleton->getAbsoluteBindPose(_rootJointIndex).trans;
|
||||
_animVars.set("rightHandPosition", targetPosition + rootTrans);
|
||||
_animVars.set("rightHandPosition", targetPosition);
|
||||
_animVars.set("rightHandRotation", targetRotation);
|
||||
}
|
||||
return;
|
||||
|
@ -995,10 +993,9 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) {
|
|||
glm::angleAxis(glm::radians(-params.localHeadPitch), X_AXIS));
|
||||
_animVars.set("headRotation", realLocalHeadOrientation);
|
||||
|
||||
auto rootTrans = _animSkeleton->getAbsoluteBindPose(_rootJointIndex).trans;
|
||||
// There's a theory that when not in hmd, we should _animVars.unset("headPosition").
|
||||
// However, until that works well, let's always request head be positioned where requested by hmd, camera, or default.
|
||||
_animVars.set("headPosition", params.localHeadPosition + rootTrans);
|
||||
_animVars.set("headPosition", params.localHeadPosition);
|
||||
} else if (!_enableAnimGraph) {
|
||||
|
||||
auto& state = _jointStates[index];
|
||||
|
|
|
@ -93,6 +93,15 @@ void EntityTreeRenderer::clear() {
|
|||
OctreeRenderer::clear();
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::reloadEntityScripts() {
|
||||
_entitiesScriptEngine->unloadAllEntityScripts();
|
||||
foreach(auto entity, _entitiesInScene) {
|
||||
if (!entity->getScript().isEmpty()) {
|
||||
_entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), entity->getScript(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::init() {
|
||||
OctreeRenderer::init();
|
||||
EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree);
|
||||
|
|
|
@ -62,6 +62,9 @@ public:
|
|||
/// clears the tree
|
||||
virtual void clear();
|
||||
|
||||
/// reloads the entity scripts, calling unload and preload
|
||||
void reloadEntityScripts();
|
||||
|
||||
/// if a renderable entity item needs a model, we will allocate it for them
|
||||
Q_INVOKABLE Model* allocateModel(const QString& url, const QString& collisionUrl);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// EntityScriptingInterface.h
|
||||
// libraries/models/src
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
|
|
|
@ -23,9 +23,6 @@ OctreeHeadlessViewer::OctreeHeadlessViewer() :
|
|||
_viewFrustum.setProjection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), DEFAULT_ASPECT_RATIO, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
}
|
||||
|
||||
OctreeHeadlessViewer::~OctreeHeadlessViewer() {
|
||||
}
|
||||
|
||||
void OctreeHeadlessViewer::init() {
|
||||
OctreeRenderer::init();
|
||||
setViewFrustum(&_viewFrustum);
|
||||
|
@ -34,8 +31,9 @@ void OctreeHeadlessViewer::init() {
|
|||
void OctreeHeadlessViewer::queryOctree() {
|
||||
char serverType = getMyNodeType();
|
||||
PacketType packetType = getMyQueryMessageType();
|
||||
|
||||
NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions();
|
||||
|
||||
|
||||
bool wantExtraDebugging = false;
|
||||
|
||||
if (wantExtraDebugging) {
|
||||
|
|
|
@ -29,7 +29,7 @@ class OctreeHeadlessViewer : public OctreeRenderer {
|
|||
Q_OBJECT
|
||||
public:
|
||||
OctreeHeadlessViewer();
|
||||
virtual ~OctreeHeadlessViewer();
|
||||
virtual ~OctreeHeadlessViewer() {};
|
||||
virtual void renderElement(OctreeElementPointer element, RenderArgs* args) { /* swallow these */ }
|
||||
|
||||
virtual void init();
|
||||
|
@ -65,7 +65,7 @@ public slots:
|
|||
|
||||
private:
|
||||
ViewFrustum _viewFrustum;
|
||||
JurisdictionListener* _jurisdictionListener;
|
||||
JurisdictionListener* _jurisdictionListener = nullptr;
|
||||
OctreeQuery _octreeQuery;
|
||||
float _voxelSizeScale;
|
||||
int _boundaryLevelAdjust;
|
||||
|
|
|
@ -54,6 +54,7 @@ void OctreeScriptingInterface::init() {
|
|||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_jurisdictionListener) {
|
||||
_managedJurisdictionListener = false;
|
||||
} else {
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
class OctreeScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OctreeScriptingInterface(OctreeEditPacketSender* packetSender = NULL,
|
||||
JurisdictionListener* jurisdictionListener = NULL);
|
||||
OctreeScriptingInterface(OctreeEditPacketSender* packetSender = NULL, JurisdictionListener* jurisdictionListener = NULL);
|
||||
|
||||
~OctreeScriptingInterface();
|
||||
|
||||
|
@ -86,8 +85,8 @@ public slots:
|
|||
|
||||
protected:
|
||||
/// attached OctreeEditPacketSender that handles queuing and sending of packets to VS
|
||||
OctreeEditPacketSender* _packetSender;
|
||||
JurisdictionListener* _jurisdictionListener;
|
||||
OctreeEditPacketSender* _packetSender = nullptr;
|
||||
JurisdictionListener* _jurisdictionListener = nullptr;
|
||||
bool _managedPacketSender;
|
||||
bool _managedJurisdictionListener;
|
||||
bool _initialized;
|
||||
|
|
|
@ -373,7 +373,10 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
projMats[0] = monoProjMat;
|
||||
|
||||
deferredTransforms[0].projection = monoProjMat;
|
||||
|
||||
deferredTransforms[0].viewInverse = monoViewMat;
|
||||
viewTransforms[0] = monoViewTransform;
|
||||
|
||||
deferredTransforms[0].stereoSide = 0.0f;
|
||||
|
||||
clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
|
||||
|
|
|
@ -27,6 +27,10 @@ ScriptCache::ScriptCache(QObject* parent) {
|
|||
// nothing to do here...
|
||||
}
|
||||
|
||||
void ScriptCache::clearCache() {
|
||||
_scriptCache.clear();
|
||||
}
|
||||
|
||||
QString ScriptCache::getScript(const QUrl& unnormalizedURL, ScriptUser* scriptUser, bool& isPending, bool reload) {
|
||||
QUrl url = ResourceManager::normalizeURL(unnormalizedURL);
|
||||
QString scriptContents;
|
||||
|
|
|
@ -28,6 +28,7 @@ class ScriptCache : public QObject, public Dependency {
|
|||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
void clearCache();
|
||||
void getScriptContents(const QString& scriptOrURL, contentAvailableCallback contentAvailable, bool forceDownload = false);
|
||||
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ void ScriptEngine::init() {
|
|||
}
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->init();
|
||||
|
||||
|
@ -405,7 +405,7 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func
|
|||
QScriptValue setterFunction = newFunction(setter, 1);
|
||||
QScriptValue getterFunction = newFunction(getter);
|
||||
|
||||
if (!parent.isNull()) {
|
||||
if (!parent.isNull() && !parent.isEmpty()) {
|
||||
QScriptValue object = globalObject().property(parent);
|
||||
if (object.isValid()) {
|
||||
object.setProperty(name, setterFunction, QScriptValue::PropertySetter);
|
||||
|
@ -559,6 +559,7 @@ void ScriptEngine::run() {
|
|||
if (!_isInitialized) {
|
||||
init();
|
||||
}
|
||||
|
||||
_isRunning = true;
|
||||
_isFinished = false;
|
||||
if (_wantSignals) {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "controllerOverlay",
|
||||
"id": "manipulatorOverlay",
|
||||
"type": "overlay",
|
||||
"data": {
|
||||
"alpha": 1.0,
|
||||
|
@ -42,7 +42,7 @@
|
|||
"children": [
|
||||
{
|
||||
"id": "spineLean",
|
||||
"type": "controller",
|
||||
"type": "manipulator",
|
||||
"data": {
|
||||
"alpha": 1.0,
|
||||
"joints": [
|
||||
|
|
Loading…
Reference in a new issue