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:
Andrew Meadows 2014-02-06 14:14:48 -08:00
parent b230f046a7
commit 802967512a
4 changed files with 105 additions and 81 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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,
}
}

View file

@ -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);
}
}
}