mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 18:44:00 +02:00
fixes for avatar paddle-hands, plus some hackery for demo
This commit is contained in:
parent
e538b4cd8d
commit
f08e639cb2
11 changed files with 60 additions and 23 deletions
|
@ -334,7 +334,7 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi
|
|||
if (handData) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
const PalmData* palm = handData->getPalm(i);
|
||||
if (palm) {
|
||||
if (palm && palm->hasPaddle()) {
|
||||
// create a disk collision proxy where the hand is
|
||||
glm::vec3 fingerAxis(0.f);
|
||||
for (size_t f = 0; f < palm->getNumFingers(); ++f) {
|
||||
|
@ -356,10 +356,12 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi
|
|||
}
|
||||
glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis;
|
||||
glm::vec3 diskNormal = palm->getNormal();
|
||||
float diskThickness = 0.08f;
|
||||
|
||||
// collide against the disk
|
||||
if (findSphereDiskPenetration(sphereCenter, sphereRadius,
|
||||
diskCenter, HAND_PADDLE_RADIUS, diskNormal, collision._penetration)) {
|
||||
diskCenter, HAND_PADDLE_RADIUS, diskThickness, diskNormal,
|
||||
collision._penetration)) {
|
||||
collision._addedVelocity = palm->getVelocity();
|
||||
return true;
|
||||
}
|
||||
|
@ -367,11 +369,14 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi
|
|||
}
|
||||
}
|
||||
|
||||
/* HACK : disable collisions with avatar proper for now -- sometimes interferes with paddle
|
||||
* TODO: disable regular collisions with hand capsules
|
||||
if (_skeletonModel.findSpherePenetration(sphereCenter, sphereRadius, collision._penetration)) {
|
||||
collision._penetration /= (float)(TREE_SCALE);
|
||||
collision._addedVelocity = getVelocity();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
|
|||
|
||||
const float THROWN_VELOCITY_SCALING = 1.5f;
|
||||
_toyBallInHand[handID] = false;
|
||||
palm.updateCollisionlessPaddleExpiry();
|
||||
glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition;
|
||||
glm::vec3 ballVelocity = ballFromHand ? palm.getRawVelocity() : palm.getTipVelocity();
|
||||
glm::quat avatarRotation = _owningAvatar->getOrientation();
|
||||
|
@ -562,6 +563,8 @@ void Hand::renderLeapHands(bool isMine) {
|
|||
continue;
|
||||
}
|
||||
glm::vec3 targetPosition = ballFromHand ? palm.getPosition() : palm.getTipPosition();
|
||||
const float BALL_FORWARD_OFFSET = 0.08f; // put the ball a bit forward of fingers
|
||||
targetPosition += BALL_FORWARD_OFFSET * palm.getNormal();
|
||||
glPushMatrix();
|
||||
|
||||
ParticleTree* particles = Application::getInstance()->getParticles()->getTree();
|
||||
|
|
|
@ -31,7 +31,7 @@ class Avatar;
|
|||
class ProgramObject;
|
||||
|
||||
const float HAND_PADDLE_OFFSET = 0.1f;
|
||||
const float HAND_PADDLE_THICKNESS = 0.05f;
|
||||
const float HAND_PADDLE_THICKNESS = 0.01f;
|
||||
const float HAND_PADDLE_RADIUS = 0.15f;
|
||||
|
||||
class Hand : public HandData {
|
||||
|
|
|
@ -98,6 +98,15 @@ void SixenseManager::update(float deltaTime) {
|
|||
// Compute current velocity from position change
|
||||
glm::vec3 rawVelocity = (position - palm->getRawPosition()) / deltaTime / 1000.f;
|
||||
palm->setRawVelocity(rawVelocity); // meters/sec
|
||||
/*
|
||||
if (i == 0)
|
||||
{
|
||||
printf("ADEBUG rawVelocity = [%e, %e, %e]\n",
|
||||
rawVelocity.x,
|
||||
rawVelocity.y,
|
||||
rawVelocity.z);
|
||||
}
|
||||
*/
|
||||
palm->setRawPosition(position);
|
||||
|
||||
// use the velocity to determine whether there's any movement (if the hand isn't new)
|
||||
|
|
|
@ -79,7 +79,8 @@ _sixenseID(SIXENSEID_INVALID),
|
|||
_numFramesWithoutData(0),
|
||||
_owningHandData(owningHandData),
|
||||
_isCollidingWithVoxel(false),
|
||||
_isCollidingWithPalm(false)
|
||||
_isCollidingWithPalm(false),
|
||||
_collisionlessPaddleExpiry(0)
|
||||
{
|
||||
for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) {
|
||||
_fingers.push_back(FingerData(this, owningHandData));
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
|
||||
class AvatarData;
|
||||
class FingerData;
|
||||
class PalmData;
|
||||
|
@ -51,7 +53,7 @@ public:
|
|||
return _basePosition + _baseOrientation * (leapPosition * LEAP_UNIT_SCALE);
|
||||
}
|
||||
glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) {
|
||||
return glm::normalize(_baseOrientation * leapDirection);
|
||||
return _baseOrientation * leapDirection;
|
||||
}
|
||||
glm::vec3 worldPositionToLeapPosition(const glm::vec3& worldPosition) const;
|
||||
glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const;
|
||||
|
@ -193,6 +195,9 @@ public:
|
|||
bool getIsCollidingWithPalm() const { return _isCollidingWithPalm; }
|
||||
void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; }
|
||||
|
||||
bool hasPaddle() const { return _collisionlessPaddleExpiry < usecTimestampNow(); }
|
||||
void updateCollisionlessPaddleExpiry() { _collisionlessPaddleExpiry = usecTimestampNow() + USECS_PER_SECOND; }
|
||||
|
||||
private:
|
||||
std::vector<FingerData> _fingers;
|
||||
glm::quat _rawRotation;
|
||||
|
@ -217,7 +222,7 @@ private:
|
|||
|
||||
bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel
|
||||
bool _isCollidingWithPalm;
|
||||
|
||||
uint64_t _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__HandData__) */
|
||||
|
|
|
@ -145,7 +145,7 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
|||
|
||||
glm::vec3 center = particle->getPosition() * (float)(TREE_SCALE);
|
||||
float radius = particle->getRadius() * (float)(TREE_SCALE);
|
||||
const float ELASTICITY = 0.95f;
|
||||
const float ELASTICITY = 0.9f;
|
||||
const float DAMPING = 0.0f;
|
||||
const float COLLISION_FREQUENCY = 0.5f;
|
||||
glm::vec3 penetration;
|
||||
|
@ -155,12 +155,26 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
|||
AvatarData* avatar = (AvatarData*)_selfAvatar;
|
||||
CollisionInfo collision;
|
||||
if (avatar->findSphereCollision(center, radius, collision)) {
|
||||
if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) {
|
||||
collision._addedVelocity /= (float)(TREE_SCALE);
|
||||
glm::vec3 relativeVelocity = collision._addedVelocity - particle->getVelocity();
|
||||
if (glm::dot(relativeVelocity, collision._penetration) < 0.f) {
|
||||
// only collide when particle and collision point are moving toward each other
|
||||
|
||||
// HACK BEGIN: to make slow particle-paddle collisions mellower
|
||||
float elasticity = ELASTICITY;
|
||||
float damping = glm::length(collision._addedVelocity) / 5.0e-5f;
|
||||
if (damping < 1.f) {
|
||||
collision._addedVelocity *= (damping * damping);
|
||||
elasticity = ELASTICITY * damping;
|
||||
damping = 0.1f;
|
||||
} else {
|
||||
damping = DAMPING;
|
||||
}
|
||||
// HACK END
|
||||
|
||||
collision._penetration /= (float)(TREE_SCALE);
|
||||
collision._addedVelocity /= (float)(TREE_SCALE);
|
||||
updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY);
|
||||
applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity);
|
||||
applyHardCollision(particle, collision._penetration, elasticity, damping, collision._addedVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
|
||||
//glm::vec3 _point;
|
||||
//glm::vec3 _normal;
|
||||
glm::vec3 _penetration;
|
||||
glm::vec3 _penetration; // depth that bodyA is penetrates bodyB
|
||||
glm::vec3 _addedVelocity;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
#include "GeometryUtil.h"
|
||||
|
@ -115,20 +116,18 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu
|
|||
}
|
||||
|
||||
bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius,
|
||||
const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal,
|
||||
const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal,
|
||||
glm::vec3& penetration) {
|
||||
glm::vec3 localCenter = sphereCenter - diskCenter;
|
||||
float verticalDistance = glm::dot(localCenter, diskNormal);
|
||||
|
||||
|
||||
if (abs(verticalDistance) < sphereRadius) {
|
||||
float axialDistance = glm::dot(localCenter, diskNormal);
|
||||
if (std::fabs(axialDistance) < (sphereRadius + 0.5f * diskThickness)) {
|
||||
// sphere hit the plane, but does it hit the disk?
|
||||
// Note: this algorithm ignores edge hits.
|
||||
glm::vec3 verticalOffset = verticalDistance * diskNormal;
|
||||
if (glm::length(localCenter - verticalOffset) < diskRadius) {
|
||||
glm::vec3 axialOffset = axialDistance * diskNormal;
|
||||
if (glm::length(localCenter - axialOffset) < diskRadius) {
|
||||
// yes, hit the disk
|
||||
penetration = (sphereRadius - abs(verticalDistance)) * diskNormal;
|
||||
if (verticalDistance < 0.f) {
|
||||
penetration = (std::fabs(axialDistance) - (sphereRadius + 0.5f * diskThickness) ) * diskNormal;
|
||||
if (axialDistance < 0.f) {
|
||||
// hit the backside of the disk, so negate penetration vector
|
||||
penetration *= -1.f;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec
|
|||
/// \param point the point location relative to sphere center (origin)
|
||||
/// \param defaultDirection the direction of the pentration when the point is near the origin
|
||||
/// \param sphereRadius the radius of the sphere
|
||||
/// \param penetration the displacement that would move the point out of penetration with the sphere
|
||||
/// \param penetration[out] the displacement that would move the point out of penetration with the sphere
|
||||
/// \return true if point is inside sphere, otherwise false
|
||||
bool findSpherePenetration(const glm::vec3& point, const glm::vec3& defaultDirection,
|
||||
float sphereRadius, glm::vec3& penetration);
|
||||
|
@ -53,9 +53,10 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu
|
|||
/// \param diskCenter center of disk
|
||||
/// \param diskRadius radius of disk
|
||||
/// \param diskNormal normal of disk plan
|
||||
/// \param penetration[out] the depth that the sphere penetrates the disk
|
||||
/// \return true if sphere touches disk (does not handle collisions with disk edge)
|
||||
bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius,
|
||||
const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal,
|
||||
const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal,
|
||||
glm::vec3& penetration);
|
||||
|
||||
bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius,
|
||||
|
|
|
@ -70,7 +70,7 @@ bool packetVersionMatch(unsigned char* packetHeader) {
|
|||
if (packetHeader[1] == versionForPacketType(packetHeader[0]) || packetHeader[0] == PACKET_TYPE_STUN_RESPONSE) {
|
||||
return true;
|
||||
} else {
|
||||
qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]);
|
||||
//qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue