mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-16 06:00:10 +02:00
Adding ModelCollisionInfo struct to get more info about collisions against avatars.
Had to disable some collisions. Will go back and make them work again soon.
This commit is contained in:
parent
0a4eec448e
commit
7a8186f1da
7 changed files with 85 additions and 38 deletions
|
@ -271,26 +271,26 @@ bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Avatar::findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
glm::vec3& penetration, int skeletonSkipIndex) const {
|
||||
bool Avatar::findSphereCollisions(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
ModelCollisionList& collisions, int skeletonSkipIndex) {
|
||||
bool didPenetrate = false;
|
||||
glm::vec3 totalPenetration;
|
||||
glm::vec3 skeletonPenetration;
|
||||
if (_skeletonModel.findSpherePenetration(penetratorCenter, penetratorRadius,
|
||||
skeletonPenetration, 1.0f, skeletonSkipIndex)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, skeletonPenetration);
|
||||
ModelCollisionInfo collisionInfo;
|
||||
int jointIndex = _skeletonModel.findSphereCollision(penetratorCenter, penetratorRadius,
|
||||
collisionInfo, 1.0f, skeletonSkipIndex);
|
||||
if (jointIndex != -1) {
|
||||
collisionInfo._model = &_skeletonModel;
|
||||
collisions.push_back(collisionInfo);
|
||||
didPenetrate = true;
|
||||
}
|
||||
glm::vec3 facePenetration;
|
||||
if (_head.getFaceModel().findSpherePenetration(penetratorCenter, penetratorRadius, facePenetration)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, facePenetration);
|
||||
jointIndex = _head.getFaceModel().findSphereCollision(penetratorCenter, penetratorRadius, collisionInfo);
|
||||
if (jointIndex != -1) {
|
||||
collisionInfo._model = &(_head.getFaceModel());
|
||||
collisions.push_back(collisionInfo);
|
||||
didPenetrate = true;
|
||||
}
|
||||
if (didPenetrate) {
|
||||
penetration = totalPenetration;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return didPenetrate;
|
||||
}
|
||||
|
||||
bool Avatar::findSphereCollisionWithHands(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision) {
|
||||
|
@ -335,14 +335,17 @@ bool Avatar::findSphereCollisionWithHands(const glm::vec3& sphereCenter, float s
|
|||
return false;
|
||||
}
|
||||
|
||||
/* adebug TODO: make this work again
|
||||
bool Avatar::findSphereCollisionWithSkeleton(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision) {
|
||||
if (_skeletonModel.findSpherePenetration(sphereCenter, sphereRadius, collision._penetration)) {
|
||||
int jointIndex = _skeletonModel.findSphereCollision(sphereCenter, sphereRadius, collision._penetration);
|
||||
if (jointIndex != -1) {
|
||||
collision._penetration /= (float)(TREE_SCALE);
|
||||
collision._addedVelocity = getVelocity();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
int Avatar::parseData(const QByteArray& packet) {
|
||||
// change in position implies movement
|
||||
|
@ -404,6 +407,22 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
|
|||
glEnd();
|
||||
}
|
||||
|
||||
void Avatar::updateCollisionFlags() {
|
||||
_collisionFlags = 0;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithEnvironment)) {
|
||||
_collisionFlags |= COLLISION_GROUP_ENVIRONMENT;
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) {
|
||||
_collisionFlags |= COLLISION_GROUP_AVATARS;
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithVoxels)) {
|
||||
_collisionFlags |= COLLISION_GROUP_VOXELS;
|
||||
}
|
||||
//if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithParticles)) {
|
||||
// _collisionFlags |= COLLISION_GROUP_PARTICLES;
|
||||
//}
|
||||
}
|
||||
|
||||
void Avatar::setScale(float scale) {
|
||||
_scale = scale;
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ enum ScreenTintLayer {
|
|||
NUM_SCREEN_TINT_LAYERS
|
||||
};
|
||||
|
||||
typedef QVector<ModelCollisionInfo> ModelCollisionList;
|
||||
|
||||
// Where one's own Avatar begins in the world (will be overwritten if avatar data file is found)
|
||||
// this is basically in the center of the ground plane. Slightly adjusted. This was asked for by
|
||||
// Grayson as he's building a street around here for demo dinner 2
|
||||
|
@ -96,11 +98,11 @@ public:
|
|||
/// Checks for penetration between the described sphere and the avatar.
|
||||
/// \param penetratorCenter the center of the penetration test sphere
|
||||
/// \param penetratorRadius the radius of the penetration test sphere
|
||||
/// \param penetration[out] the vector in which to store the penetration
|
||||
/// \param collisions[out] a list of collisions
|
||||
/// \param skeletonSkipIndex if not -1, the index of a joint to skip (along with its descendents) in the skeleton model
|
||||
/// \return whether or not the sphere penetrated
|
||||
bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
glm::vec3& penetration, int skeletonSkipIndex = -1) const;
|
||||
bool findSphereCollisions(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
ModelCollisionList& collisions, int skeletonSkipIndex = -1);
|
||||
|
||||
/// Checks for collision between the a sphere and the avatar's (paddle) hands.
|
||||
/// \param collisionCenter the center of the penetration test sphere
|
||||
|
@ -114,7 +116,7 @@ public:
|
|||
/// \param collisionRadius the radius of the penetration test sphere
|
||||
/// \param collision[out] the details of the collision point
|
||||
/// \return whether or not the sphere collided
|
||||
bool findSphereCollisionWithSkeleton(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision);
|
||||
//bool findSphereCollisionWithSkeleton(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision);
|
||||
|
||||
virtual bool isMyAvatar() { return false; }
|
||||
|
||||
|
@ -124,6 +126,9 @@ public:
|
|||
|
||||
float getHeight() const;
|
||||
|
||||
public slots:
|
||||
void updateCollisionFlags();
|
||||
|
||||
protected:
|
||||
Head _head;
|
||||
Hand _hand;
|
||||
|
|
|
@ -84,8 +84,7 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
|
||||
if (isMine) {
|
||||
_buckyBalls.simulate(deltaTime);
|
||||
// TODO: recover this stuff after avatar-avatar collisions work again - Andrew
|
||||
//updateCollisions();
|
||||
updateCollisions();
|
||||
}
|
||||
|
||||
calculateGeometry();
|
||||
|
@ -172,6 +171,7 @@ void Hand::updateCollisions() {
|
|||
int leftPalmIndex, rightPalmIndex;
|
||||
getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);
|
||||
|
||||
ModelCollisionList collisions;
|
||||
// check for collisions
|
||||
for (size_t i = 0; i < getNumPalms(); i++) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
|
@ -224,9 +224,10 @@ void Hand::updateCollisions() {
|
|||
}
|
||||
}
|
||||
}
|
||||
glm::vec3 avatarPenetration;
|
||||
if (avatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, avatarPenetration)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, avatarPenetration);
|
||||
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
|
||||
for (size_t j = 0; j < collisions.size(); ++j) {
|
||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||
}
|
||||
// Check for collisions with the other avatar's leap palms
|
||||
}
|
||||
}
|
||||
|
@ -234,18 +235,23 @@ void Hand::updateCollisions() {
|
|||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandsCollideWithSelf)) {
|
||||
// and the current avatar (ignoring everything below the parent of the parent of the last free joint)
|
||||
glm::vec3 owningPenetration;
|
||||
collisions.clear();
|
||||
const Model& skeletonModel = _owningAvatar->getSkeletonModel();
|
||||
int skipIndex = skeletonModel.getParentJointIndex(skeletonModel.getParentJointIndex(
|
||||
skeletonModel.getLastFreeJointIndex((i == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() :
|
||||
(i == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1)));
|
||||
if (_owningAvatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, owningPenetration, skipIndex)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, owningPenetration);
|
||||
if (_owningAvatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions, skipIndex)) {
|
||||
for (size_t j = 0; j < collisions.size(); ++j) {
|
||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// un-penetrate
|
||||
palm.addToPosition(-totalPenetration);
|
||||
|
||||
// we recycle the collisions container, so we clear it for the next loop
|
||||
collisions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,8 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
updateCollisionWithVoxels(deltaTime, radius);
|
||||
}
|
||||
if (_collisionFlags & COLLISION_GROUP_AVATARS) {
|
||||
updateCollisionWithAvatars(deltaTime);
|
||||
// TODO: Andrew to implement this
|
||||
//updateCollisionWithAvatars(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1017,8 +1018,9 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
|
|||
glm::vec3 pos = palmProxies[i]._position;
|
||||
// query against avatar
|
||||
if (avatar->findSphereCollisionWithSkeleton(pos, palmProxies[i]._radius, collisionInfo)) {
|
||||
// TODO: Andrew to make this work
|
||||
// push hand out of penetration
|
||||
palms[palmProxies[i]._palmIndex].addToPosition(0.5f * collisionInfo._penetration);
|
||||
//palms[palmProxies[i]._palmIndex].addToPosition(0.5f * collisionInfo._penetration * float(TREE_SCALE));
|
||||
// print results
|
||||
//distance = glm::length(collisionInfo._penetration);
|
||||
//printf("collision i = %d p = [%e, %e, %e] d = %e\n", i, pos.x, pos.y, pos.z, distance);
|
||||
|
|
|
@ -437,11 +437,11 @@ bool Model::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Model::findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
glm::vec3& penetration, float boneScale, int skipIndex) const {
|
||||
bool Model::findSphereCollision(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
ModelCollisionInfo& collisionInfo, float boneScale, int skipIndex) const {
|
||||
int jointIndex = -1;
|
||||
const glm::vec3 relativeCenter = penetratorCenter - _translation;
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
bool didPenetrate = false;
|
||||
glm::vec3 totalPenetration;
|
||||
float radiusScale = extractUniformScale(_scale) * boneScale;
|
||||
for (int i = 0; i < _jointStates.size(); i++) {
|
||||
|
@ -468,12 +468,16 @@ bool Model::findSpherePenetration(const glm::vec3& penetratorCenter, float penet
|
|||
if (findSphereCapsuleConePenetration(relativeCenter, penetratorRadius, start, end,
|
||||
startRadius, endRadius, bonePenetration)) {
|
||||
totalPenetration = addPenetrations(totalPenetration, bonePenetration);
|
||||
didPenetrate = true;
|
||||
// TODO: Andrew to try to keep the joint furthest toward the root
|
||||
jointIndex = i;
|
||||
}
|
||||
outerContinue: ;
|
||||
}
|
||||
if (didPenetrate) {
|
||||
penetration = totalPenetration;
|
||||
if (jointIndex != -1) {
|
||||
// TODO? Andrew to store contactPoint
|
||||
// don't store collisionInfo._model at this stage, let the outer context do that
|
||||
collisionInfo._penetration = totalPenetration;
|
||||
collisionInfo._jointIndex = jointIndex;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -17,6 +17,16 @@
|
|||
#include "ProgramObject.h"
|
||||
#include "TextureCache.h"
|
||||
|
||||
class Model;
|
||||
|
||||
// TODO: Andrew to move this into its own file
|
||||
class ModelCollisionInfo : public CollisionInfo {
|
||||
public:
|
||||
ModelCollisionInfo() : CollisionInfo(), _model(NULL), _jointIndex(-1) {}
|
||||
Model* _model;
|
||||
int _jointIndex;
|
||||
};
|
||||
|
||||
/// A generic 3D model displaying geometry loaded from a URL.
|
||||
class Model : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -149,8 +159,8 @@ public:
|
|||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
|
||||
|
||||
bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
glm::vec3& penetration, float boneScale = 1.0f, int skipIndex = -1) const;
|
||||
bool findSphereCollision(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
ModelCollisionInfo& collision, float boneScale = 1.0f, int skipIndex = -1) const;
|
||||
|
||||
void renderCollisionProxies(float alpha);
|
||||
|
||||
|
|
|
@ -186,8 +186,9 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
|||
CollisionInfo collisionInfo;
|
||||
collisionInfo._damping = DAMPING;
|
||||
collisionInfo._elasticity = ELASTICITY;
|
||||
if (avatar->findSphereCollisionWithHands(center, radius, collisionInfo) ||
|
||||
avatar->findSphereCollisionWithSkeleton(center, radius, collisionInfo)) {
|
||||
if (avatar->findSphereCollisionWithHands(center, radius, collisionInfo)) {
|
||||
// TODO: Andrew to resurrect particles-vs-avatar body collisions
|
||||
//avatar->findSphereCollisionWithSkeleton(center, radius, collisionInfo)) {
|
||||
collisionInfo._addedVelocity /= (float)(TREE_SCALE);
|
||||
glm::vec3 relativeVelocity = collisionInfo._addedVelocity - particle->getVelocity();
|
||||
if (glm::dot(relativeVelocity, collisionInfo._penetration) < 0.f) {
|
||||
|
|
Loading…
Reference in a new issue