mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-16 08:40:11 +02:00
Splitting rendering of avatars and their collision proxies.
Also disabling old hand-avatar interactions and trying to use new stuff.
This commit is contained in:
parent
b230f046a7
commit
802967512a
4 changed files with 105 additions and 81 deletions
|
@ -160,7 +160,13 @@ void Avatar::render(bool forceRenderHead) {
|
|||
Glower glower(_moving && glm::length(toTarget) > GLOW_DISTANCE ? 1.0f : 0.0f);
|
||||
|
||||
// render body
|
||||
renderBody(forceRenderHead);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) {
|
||||
_skeletonModel.renderCollisionProxies(1.f);
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
renderBody(forceRenderHead);
|
||||
}
|
||||
|
||||
// render sphere when far away
|
||||
const float MAX_ANGLE = 10.f;
|
||||
|
|
|
@ -111,9 +111,6 @@ void AvatarManager::updateAvatars(float deltaTime) {
|
|||
}
|
||||
|
||||
void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
return;
|
||||
}
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::renderAvatars()");
|
||||
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors);
|
||||
|
|
|
@ -84,15 +84,14 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
|
||||
if (isMine) {
|
||||
_buckyBalls.simulate(deltaTime);
|
||||
updateCollisions();
|
||||
// TODO: recover this stuff after avatar-avatar collisions work again - Andrew
|
||||
//updateCollisions();
|
||||
}
|
||||
|
||||
calculateGeometry();
|
||||
|
||||
if (isMine) {
|
||||
|
||||
// Iterate hand controllers, take actions as needed
|
||||
|
||||
for (size_t i = 0; i < getNumPalms(); ++i) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
if (palm.isActive()) {
|
||||
|
@ -182,52 +181,54 @@ void Hand::updateCollisions() {
|
|||
float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale();
|
||||
glm::vec3 totalPenetration;
|
||||
|
||||
// check other avatars
|
||||
foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||
if (avatar == _owningAvatar) {
|
||||
// don't collid with our own hands
|
||||
continue;
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
||||
// Check for palm collisions
|
||||
glm::vec3 myPalmPosition = palm.getPosition();
|
||||
float palmCollisionDistance = 0.1f;
|
||||
bool wasColliding = palm.getIsCollidingWithPalm();
|
||||
palm.setIsCollidingWithPalm(false);
|
||||
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
|
||||
for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) {
|
||||
PalmData& otherPalm = avatar->getHand().getPalms()[j];
|
||||
if (!otherPalm.isActive()) {
|
||||
continue;
|
||||
}
|
||||
glm::vec3 otherPalmPosition = otherPalm.getPosition();
|
||||
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
||||
palm.setIsCollidingWithPalm(true);
|
||||
if (!wasColliding) {
|
||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||
PALM_COLLIDE_FREQUENCY,
|
||||
PALM_COLLIDE_DURATION_MAX,
|
||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
||||
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
||||
// add slapback here
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) {
|
||||
// check other avatars
|
||||
foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||
if (avatar == _owningAvatar) {
|
||||
// don't collid with our own hands
|
||||
continue;
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
||||
// Check for palm collisions
|
||||
glm::vec3 myPalmPosition = palm.getPosition();
|
||||
float palmCollisionDistance = 0.1f;
|
||||
bool wasColliding = palm.getIsCollidingWithPalm();
|
||||
palm.setIsCollidingWithPalm(false);
|
||||
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
|
||||
for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) {
|
||||
PalmData& otherPalm = avatar->getHand().getPalms()[j];
|
||||
if (!otherPalm.isActive()) {
|
||||
continue;
|
||||
}
|
||||
glm::vec3 otherPalmPosition = otherPalm.getPosition();
|
||||
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
||||
palm.setIsCollidingWithPalm(true);
|
||||
if (!wasColliding) {
|
||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||
PALM_COLLIDE_FREQUENCY,
|
||||
PALM_COLLIDE_DURATION_MAX,
|
||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
||||
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
||||
// add slapback here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
glm::vec3 avatarPenetration;
|
||||
if (avatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, avatarPenetration)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, avatarPenetration);
|
||||
// Check for collisions with the other avatar's leap palms
|
||||
glm::vec3 avatarPenetration;
|
||||
if (avatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, avatarPenetration)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, avatarPenetration);
|
||||
// Check for collisions with the other avatar's leap palms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,14 +279,14 @@ void Hand::calculateGeometry() {
|
|||
FingerData& finger = palm.getFingers()[f];
|
||||
if (finger.isActive()) {
|
||||
const float standardBallRadius = FINGERTIP_COLLISION_RADIUS;
|
||||
_leapFingerTipBalls.resize(_leapFingerTipBalls.size() + 1);
|
||||
HandBall& ball = _leapFingerTipBalls.back();
|
||||
HandBall ball;
|
||||
ball.rotation = getBaseOrientation();
|
||||
ball.position = finger.getTipPosition();
|
||||
ball.radius = standardBallRadius;
|
||||
ball.touchForce = 0.0;
|
||||
ball.isCollidable = true;
|
||||
ball.isColliding = false;
|
||||
_leapFingerTipBalls.push_back(ball);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,14 +301,14 @@ void Hand::calculateGeometry() {
|
|||
FingerData& finger = palm.getFingers()[f];
|
||||
if (finger.isActive()) {
|
||||
const float standardBallRadius = 0.005f;
|
||||
_leapFingerRootBalls.resize(_leapFingerRootBalls.size() + 1);
|
||||
HandBall& ball = _leapFingerRootBalls.back();
|
||||
HandBall ball;
|
||||
ball.rotation = getBaseOrientation();
|
||||
ball.position = finger.getRootPosition();
|
||||
ball.radius = standardBallRadius;
|
||||
ball.touchForce = 0.0;
|
||||
ball.isCollidable = true;
|
||||
ball.isColliding = false;
|
||||
_leapFingerRootBalls.push_back(ball);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -473,8 +474,3 @@ void Hand::setLeapHands(const std::vector<glm::vec3>& handPositions,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -380,7 +380,12 @@ void MyAvatar::renderDebugBodyPoints() {
|
|||
void MyAvatar::render(bool forceRenderHead) {
|
||||
|
||||
// render body
|
||||
renderBody(forceRenderHead);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) {
|
||||
_skeletonModel.renderCollisionProxies(1.f);
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
renderBody(forceRenderHead);
|
||||
}
|
||||
|
||||
//renderDebugBodyPoints();
|
||||
|
||||
|
@ -753,6 +758,21 @@ void MyAvatar::updateCollisionSound(const glm::vec3 &penetration, float deltaTim
|
|||
}
|
||||
}
|
||||
|
||||
// this is a work in progress
|
||||
class PalmCollisionProxy {
|
||||
public:
|
||||
PalmCollisionProxy() : _palmIndex(-1), _position(0.f), _radius(0.f) {}
|
||||
|
||||
PalmCollisionProxy(int index, const glm::vec3& position, float radius) :
|
||||
_palmIndex(index), _position(position), _radius(radius) {}
|
||||
|
||||
int _palmIndex;
|
||||
glm::vec3 _position;
|
||||
float _radius;
|
||||
};
|
||||
|
||||
const float DEFAULT_HAND_RADIUS = 0.1f;
|
||||
|
||||
void MyAvatar::updateAvatarCollisions(float deltaTime) {
|
||||
// Reset detector for nearest avatar
|
||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
||||
|
@ -761,18 +781,28 @@ void MyAvatar::updateAvatarCollisions(float deltaTime) {
|
|||
// no need to compute a bunch of stuff if we have one or fewer avatars
|
||||
return;
|
||||
}
|
||||
float myRadius = (0.5f + COLLISION_RADIUS_SCALE) * getHeight();
|
||||
float myRadius = getHeight();
|
||||
|
||||
// precompute hand proxies before we start walking the avatarlist
|
||||
QVector<glm::vec3> handPositions;
|
||||
QVector<PalmCollisionProxy> palmProxies;
|
||||
std::vector<PalmData>& palms = getHand().getPalms();
|
||||
size_t numPalms = palms.size();
|
||||
glm::vec3 position;
|
||||
if (_skeletonModel.getLeftHandPosition(position)) {
|
||||
handPositions.push_back(position);
|
||||
for (int i = 0; i < numPalms; ++i) {
|
||||
PalmData& palm = palms[i];
|
||||
if (palm.getSixenseID() == SIXENSE_CONTROLLER_ID_LEFT_HAND) {
|
||||
if (_skeletonModel.getLeftHandPosition(position)) {
|
||||
float radius = DEFAULT_HAND_RADIUS;
|
||||
palmProxies.push_back(PalmCollisionProxy(i, position, radius));
|
||||
}
|
||||
} else if (palm.getSixenseID() == SIXENSE_CONTROLLER_ID_RIGHT_HAND) {
|
||||
if (_skeletonModel.getRightHandPosition(position)) {
|
||||
float radius = DEFAULT_HAND_RADIUS;
|
||||
palmProxies.push_back(PalmCollisionProxy(i, position, radius));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_skeletonModel.getRightHandPosition(position)) {
|
||||
handPositions.push_back(position);
|
||||
}
|
||||
|
||||
|
||||
CollisionInfo collisionInfo;
|
||||
foreach (const AvatarSharedPointer& avatarPointer, avatars) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||
|
@ -784,22 +814,17 @@ void MyAvatar::updateAvatarCollisions(float deltaTime) {
|
|||
if (_distanceToNearestAvatar > distance) {
|
||||
_distanceToNearestAvatar = distance;
|
||||
}
|
||||
float theirRadius = (0.5f + COLLISION_RADIUS_SCALE) * avatar->getHeight();
|
||||
float theirRadius = avatar->getHeight();
|
||||
if (distance < myRadius + theirRadius) {
|
||||
//printf("potential avatar collision d = %e\n", distance);
|
||||
// collide the hands like spheres
|
||||
for (int i = 0; i < handPositions.size(); ++i) {
|
||||
glm::vec3 pos = handPositions[i];
|
||||
distance = glm::length(_position - handPositions[i]);
|
||||
printf("i = %d p = [%e, %e, %e] d = %e\n", i, pos.x, pos.y, pos.z, distance);
|
||||
|
||||
// give each hand a spherical collision proxy
|
||||
const float DEFAULT_HAND_RADIUS = 0.1f;
|
||||
|
||||
for (int i = 0; i < palmProxies.size(); ++i) {
|
||||
glm::vec3 pos = palmProxies[i]._position;
|
||||
// query against avatar
|
||||
if (avatar->findSphereCollisionWithSkeleton(pos, DEFAULT_HAND_RADIUS, collisionInfo)) {
|
||||
if (avatar->findSphereCollisionWithSkeleton(pos, palmProxies[i]._radius, collisionInfo)) {
|
||||
// push hand out of penetration
|
||||
palms[palmProxies[i]._palmIndex].addToPosition(0.5f * collisionInfo._penetration);
|
||||
// print results
|
||||
printf("collision i = %d p = [%e, %e, %e] d = %e\n", i, pos.x, pos.y, pos.z, distance);
|
||||
//distance = glm::length(collisionInfo._penetration);
|
||||
//printf("collision i = %d p = [%e, %e, %e] d = %e\n", i, pos.x, pos.y, pos.z, distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue