mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels
This commit is contained in:
commit
32cf08ce65
11 changed files with 106 additions and 30 deletions
|
@ -353,6 +353,7 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderSkeletonCollisionShapes);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderHeadCollisionShapes);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderBoundingCollisionShapes);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::CollideAsRagDoll);
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu,
|
||||
|
|
|
@ -311,6 +311,7 @@ namespace MenuOption {
|
|||
const QString CascadedShadows = "Cascaded";
|
||||
const QString Chat = "Chat...";
|
||||
const QString ChatCircling = "Chat Circling";
|
||||
const QString CollideAsRagDoll = "Collide As RagDoll";
|
||||
const QString CollideWithAvatars = "Collide With Avatars";
|
||||
const QString CollideWithEnvironment = "Collide With World Boundaries";
|
||||
const QString CollideWithParticles = "Collide With Particles";
|
||||
|
|
|
@ -23,7 +23,10 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar) :
|
|||
|
||||
void SkeletonModel::setJointStates(QVector<JointState> states) {
|
||||
Model::setJointStates(states);
|
||||
_ragDoll.init(_jointStates);
|
||||
|
||||
if (isActive() && _owningAvatar->isMyAvatar()) {
|
||||
_ragDoll.init(_jointStates);
|
||||
}
|
||||
}
|
||||
|
||||
const float PALM_PRIORITY = 3.0f;
|
||||
|
@ -88,7 +91,7 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
|||
}
|
||||
|
||||
void SkeletonModel::simulateRagDoll(float deltaTime) {
|
||||
_ragDoll.slaveToSkeleton(_jointStates, 0.5f);
|
||||
_ragDoll.slaveToSkeleton(_jointStates, 0.1f); // fraction = 0.1f left intentionally low for demo purposes
|
||||
|
||||
float MIN_CONSTRAINT_ERROR = 0.005f; // 5mm
|
||||
int MAX_ITERATIONS = 4;
|
||||
|
@ -141,7 +144,9 @@ void SkeletonModel::getBodyShapes(QVector<const Shape*>& shapes) const {
|
|||
void SkeletonModel::renderIKConstraints() {
|
||||
renderJointConstraints(getRightHandJointIndex());
|
||||
renderJointConstraints(getLeftHandJointIndex());
|
||||
renderRagDoll();
|
||||
if (isActive() && _owningAvatar->isMyAvatar()) {
|
||||
renderRagDoll();
|
||||
}
|
||||
}
|
||||
|
||||
class IndexValue {
|
||||
|
@ -254,6 +259,15 @@ void SkeletonModel::updateJointState(int index) {
|
|||
}
|
||||
}
|
||||
|
||||
void SkeletonModel::updateShapePositions() {
|
||||
if (isActive() && _owningAvatar->isMyAvatar() &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::CollideAsRagDoll)) {
|
||||
_ragDoll.updateShapes(_jointShapes, _rotation, _translation);
|
||||
} else {
|
||||
Model::updateShapePositions();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
||||
if (!_owningAvatar->isMyAvatar() || Application::getInstance()->getPrioVR()->isActive()) {
|
||||
return;
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
|
||||
void simulate(float deltaTime, bool fullUpdate = true);
|
||||
void simulateRagDoll(float deltaTime);
|
||||
void updateShapePositions();
|
||||
|
||||
/// \param jointIndex index of hand joint
|
||||
/// \param shapes[out] list in which is stored pointers to hand shapes
|
||||
|
|
|
@ -140,7 +140,7 @@ public:
|
|||
void clearShapes();
|
||||
void rebuildShapes();
|
||||
void resetShapePositions();
|
||||
void updateShapePositions();
|
||||
virtual void updateShapePositions();
|
||||
void renderJointCollisionShapes(float alpha);
|
||||
void renderBoundingCollisionShapes(float alpha);
|
||||
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
|
||||
#include <CollisionInfo.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <CapsuleShape.h>
|
||||
#include <SphereShape.h>
|
||||
|
||||
#include "RagDoll.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// FixedConstraint
|
||||
// ----------------------------------------------------------------------------
|
||||
FixedConstraint::FixedConstraint() : _point(NULL), _anchor(0.0f, 0.0f, 0.0f) {
|
||||
FixedConstraint::FixedConstraint(glm::vec3* point, const glm::vec3& anchor) : _point(point), _anchor(anchor) {
|
||||
}
|
||||
|
||||
float FixedConstraint::enforce() {
|
||||
|
@ -42,9 +44,9 @@ void FixedConstraint::setAnchor(const glm::vec3& anchor) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// DistanceConstraint
|
||||
// ----------------------------------------------------------------------------
|
||||
DistanceConstraint::DistanceConstraint(glm::vec3* pointA, glm::vec3* pointB) : _distance(-1.0f) {
|
||||
_points[0] = pointA;
|
||||
_points[1] = pointB;
|
||||
DistanceConstraint::DistanceConstraint(glm::vec3* startPoint, glm::vec3* endPoint) : _distance(-1.0f) {
|
||||
_points[0] = startPoint;
|
||||
_points[1] = endPoint;
|
||||
_distance = glm::distance(*(_points[0]), *(_points[1]));
|
||||
}
|
||||
|
||||
|
@ -70,6 +72,28 @@ float DistanceConstraint::enforce() {
|
|||
return glm::abs(newDistance - _distance);
|
||||
}
|
||||
|
||||
void DistanceConstraint::updateProxyShape(Shape* shape, const glm::quat& rotation, const glm::vec3& translation) const {
|
||||
if (!shape) {
|
||||
return;
|
||||
}
|
||||
switch (shape->getType()) {
|
||||
case Shape::SPHERE_SHAPE: {
|
||||
// sphere collides at endPoint
|
||||
SphereShape* sphere = static_cast<SphereShape*>(shape);
|
||||
sphere->setPosition(translation + rotation * (*_points[1]));
|
||||
}
|
||||
break;
|
||||
case Shape::CAPSULE_SHAPE: {
|
||||
// capsule collides from startPoint to endPoint
|
||||
CapsuleShape* capsule = static_cast<CapsuleShape*>(shape);
|
||||
capsule->setEndPoints(translation + rotation * (*_points[0]), translation + rotation * (*_points[1]));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RagDoll
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -90,12 +114,16 @@ void RagDoll::init(const QVector<JointState>& states) {
|
|||
_points.push_back(state.getPosition());
|
||||
int parentIndex = state.getFBXJoint().parentIndex;
|
||||
assert(parentIndex < i);
|
||||
if (parentIndex != -1) {
|
||||
if (parentIndex == -1) {
|
||||
FixedConstraint* anchor = new FixedConstraint(&(_points[i]), glm::vec3(0.0f));
|
||||
_constraints.push_back(anchor);
|
||||
} else {
|
||||
DistanceConstraint* stick = new DistanceConstraint(&(_points[i]), &(_points[parentIndex]));
|
||||
_constraints.push_back(stick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete all data.
|
||||
void RagDoll::clear() {
|
||||
int numConstraints = _constraints.size();
|
||||
|
@ -129,3 +157,11 @@ float RagDoll::enforceConstraints() {
|
|||
}
|
||||
return maxDistance;
|
||||
}
|
||||
|
||||
void RagDoll::updateShapes(const QVector<Shape*>& shapes, const glm::quat& rotation, const glm::vec3& translation) const {
|
||||
int numShapes = shapes.size();
|
||||
int numConstraints = _constraints.size();
|
||||
for (int i = 0; i < numShapes && i < numConstraints; ++i) {
|
||||
_constraints[i]->updateProxyShape(shapes[i], rotation, translation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "renderer/Model.h"
|
||||
|
||||
class Shape;
|
||||
|
||||
class Constraint {
|
||||
public:
|
||||
Constraint() {}
|
||||
|
@ -22,11 +24,20 @@ public:
|
|||
/// Enforce contraint by moving relevant points.
|
||||
/// \return max distance of point movement
|
||||
virtual float enforce() = 0;
|
||||
|
||||
/// \param shape pointer to shape that will be this Constraint's collision proxy
|
||||
/// \param rotation rotation into shape's collision frame
|
||||
/// \param translation translation into shape's collision frame
|
||||
/// Moves the shape such that it will collide at this constraint's position
|
||||
virtual void updateProxyShape(Shape* shape, const glm::quat& rotation, const glm::vec3& translation) const {}
|
||||
|
||||
protected:
|
||||
int _type;
|
||||
};
|
||||
|
||||
class FixedConstraint : public Constraint {
|
||||
public:
|
||||
FixedConstraint();
|
||||
FixedConstraint(glm::vec3* point, const glm::vec3& anchor);
|
||||
float enforce();
|
||||
void setPoint(glm::vec3* point);
|
||||
void setAnchor(const glm::vec3& anchor);
|
||||
|
@ -37,10 +48,11 @@ private:
|
|||
|
||||
class DistanceConstraint : public Constraint {
|
||||
public:
|
||||
DistanceConstraint(glm::vec3* pointA, glm::vec3* pointB);
|
||||
DistanceConstraint(glm::vec3* startPoint, glm::vec3* endPoint);
|
||||
DistanceConstraint(const DistanceConstraint& other);
|
||||
float enforce();
|
||||
void setDistance(float distance);
|
||||
void updateProxyShape(Shape* shape, const glm::quat& rotation, const glm::vec3& translation) const;
|
||||
private:
|
||||
float _distance;
|
||||
glm::vec3* _points[2];
|
||||
|
@ -69,7 +81,12 @@ public:
|
|||
float enforceConstraints();
|
||||
|
||||
const QVector<glm::vec3>& getPoints() const { return _points; }
|
||||
|
||||
|
||||
/// \param shapes list of shapes to be updated with new positions
|
||||
/// \param rotation rotation into shapes' collision frame
|
||||
/// \param translation translation into shapes' collision frame
|
||||
void updateShapes(const QVector<Shape*>& shapes, const glm::quat& rotation, const glm::vec3& translation) const;
|
||||
|
||||
private:
|
||||
QVector<Constraint*> _constraints;
|
||||
QVector<glm::vec3> _points;
|
||||
|
|
|
@ -894,14 +894,15 @@ FBXBlendshape extractBlendshape(const FBXNode& object) {
|
|||
}
|
||||
|
||||
void setTangents(FBXMesh& mesh, int firstIndex, int secondIndex) {
|
||||
glm::vec3 normal = glm::normalize(mesh.normals.at(firstIndex));
|
||||
const glm::vec3& normal = mesh.normals.at(firstIndex);
|
||||
glm::vec3 bitangent = glm::cross(normal, mesh.vertices.at(secondIndex) - mesh.vertices.at(firstIndex));
|
||||
if (glm::length(bitangent) < EPSILON) {
|
||||
return;
|
||||
}
|
||||
glm::vec2 texCoordDelta = mesh.texCoords.at(secondIndex) - mesh.texCoords.at(firstIndex);
|
||||
mesh.tangents[firstIndex] += glm::cross(glm::angleAxis(
|
||||
- atan2f(-texCoordDelta.t, texCoordDelta.s), normal) * glm::normalize(bitangent), normal);
|
||||
glm::vec3 normalizedNormal = glm::normalize(normal);
|
||||
mesh.tangents[firstIndex] += glm::cross(glm::angleAxis(-atan2f(-texCoordDelta.t, texCoordDelta.s), normalizedNormal) *
|
||||
glm::normalize(bitangent), normalizedNormal);
|
||||
}
|
||||
|
||||
QVector<int> getIndices(const QVector<QString> ids, QVector<QString> modelIDs) {
|
||||
|
|
|
@ -313,7 +313,7 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
|
|||
QByteArray postData;
|
||||
postData.append("grant_type=password&");
|
||||
postData.append("username=" + login + "&");
|
||||
postData.append("password=" + password + "&");
|
||||
postData.append("password=" + QUrl::toPercentEncoding(password) + "&");
|
||||
postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
|
||||
|
||||
request.setUrl(grantURL);
|
||||
|
|
|
@ -33,20 +33,7 @@ CapsuleShape::CapsuleShape(float radius, float halfHeight, const glm::vec3& posi
|
|||
|
||||
CapsuleShape::CapsuleShape(float radius, const glm::vec3& startPoint, const glm::vec3& endPoint) :
|
||||
Shape(Shape::CAPSULE_SHAPE), _radius(radius), _halfHeight(0.0f) {
|
||||
glm::vec3 axis = endPoint - startPoint;
|
||||
_position = 0.5f * (endPoint + startPoint);
|
||||
float height = glm::length(axis);
|
||||
if (height > EPSILON) {
|
||||
_halfHeight = 0.5f * height;
|
||||
axis /= height;
|
||||
glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
|
||||
float angle = glm::angle(axis, yAxis);
|
||||
if (angle > EPSILON) {
|
||||
axis = glm::normalize(glm::cross(yAxis, axis));
|
||||
_rotation = glm::angleAxis(angle, axis);
|
||||
}
|
||||
}
|
||||
updateBoundingRadius();
|
||||
setEndPoints(startPoint, endPoint);
|
||||
}
|
||||
|
||||
/// \param[out] startPoint is the center of start cap
|
||||
|
@ -80,3 +67,20 @@ void CapsuleShape::setRadiusAndHalfHeight(float radius, float halfHeight) {
|
|||
updateBoundingRadius();
|
||||
}
|
||||
|
||||
void CapsuleShape::setEndPoints(const glm::vec3& startPoint, const glm::vec3& endPoint) {
|
||||
glm::vec3 axis = endPoint - startPoint;
|
||||
_position = 0.5f * (endPoint + startPoint);
|
||||
float height = glm::length(axis);
|
||||
if (height > EPSILON) {
|
||||
_halfHeight = 0.5f * height;
|
||||
axis /= height;
|
||||
glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
|
||||
float angle = glm::angle(axis, yAxis);
|
||||
if (angle > EPSILON) {
|
||||
axis = glm::normalize(glm::cross(yAxis, axis));
|
||||
_rotation = glm::angleAxis(angle, axis);
|
||||
}
|
||||
}
|
||||
updateBoundingRadius();
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
void setRadius(float radius);
|
||||
void setHalfHeight(float height);
|
||||
void setRadiusAndHalfHeight(float radius, float height);
|
||||
void setEndPoints(const glm::vec3& startPoint, const glm::vec3& endPoint);
|
||||
|
||||
protected:
|
||||
void updateBoundingRadius() { _boundingRadius = _radius + _halfHeight; }
|
||||
|
|
Loading…
Reference in a new issue