mirror of
https://github.com/overte-org/overte.git
synced 2025-07-22 18:34:56 +02:00
It is now possible to "poke" moveable parts of the avatar skeleton.
This commit is contained in:
parent
e2e02fc855
commit
e73c9f7095
5 changed files with 52 additions and 21 deletions
|
@ -276,16 +276,12 @@ bool Avatar::findSphereCollisions(const glm::vec3& penetratorCenter, float penet
|
||||||
bool didPenetrate = false;
|
bool didPenetrate = false;
|
||||||
glm::vec3 skeletonPenetration;
|
glm::vec3 skeletonPenetration;
|
||||||
ModelCollisionInfo collisionInfo;
|
ModelCollisionInfo collisionInfo;
|
||||||
int jointIndex = _skeletonModel.findSphereCollision(penetratorCenter, penetratorRadius,
|
if (_skeletonModel.findSphereCollision(penetratorCenter, penetratorRadius, collisionInfo, 1.0f, skeletonSkipIndex)) {
|
||||||
collisionInfo, 1.0f, skeletonSkipIndex);
|
|
||||||
if (jointIndex != -1) {
|
|
||||||
collisionInfo._model = &_skeletonModel;
|
collisionInfo._model = &_skeletonModel;
|
||||||
collisions.push_back(collisionInfo);
|
collisions.push_back(collisionInfo);
|
||||||
didPenetrate = true;
|
didPenetrate = true;
|
||||||
}
|
}
|
||||||
glm::vec3 facePenetration;
|
if (_head.getFaceModel().findSphereCollision(penetratorCenter, penetratorRadius, collisionInfo)) {
|
||||||
jointIndex = _head.getFaceModel().findSphereCollision(penetratorCenter, penetratorRadius, collisionInfo);
|
|
||||||
if (jointIndex != -1) {
|
|
||||||
collisionInfo._model = &(_head.getFaceModel());
|
collisionInfo._model = &(_head.getFaceModel());
|
||||||
collisions.push_back(collisionInfo);
|
collisions.push_back(collisionInfo);
|
||||||
didPenetrate = true;
|
didPenetrate = true;
|
||||||
|
@ -447,18 +443,13 @@ float Avatar::getHeight() const {
|
||||||
return extents.maximum.y - extents.minimum.y;
|
return extents.maximum.y - extents.minimum.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::poke(ModelCollisionInfo& collision) {
|
bool Avatar::poke(ModelCollisionInfo& collision) {
|
||||||
if (collision._model == &_skeletonModel
|
// ATM poke() can only affect the Skeleton (not the head)
|
||||||
&& collision._jointIndex != -1) {
|
// TODO: make poke affect head
|
||||||
// TODO: Andrew to make this work
|
if (collision._model == &_skeletonModel && collision._jointIndex != -1) {
|
||||||
printf("ADEBUG model = 0x%x joint = %d p = [%e, %e, %e]\n",
|
return _skeletonModel.poke(collision);
|
||||||
collision._model,
|
|
||||||
collision._jointIndex,
|
|
||||||
collision._contactPoint.x,
|
|
||||||
collision._contactPoint.y,
|
|
||||||
collision._contactPoint.z
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Avatar::getPelvisFloatingHeight() const {
|
float Avatar::getPelvisFloatingHeight() const {
|
||||||
|
|
|
@ -128,7 +128,9 @@ public:
|
||||||
|
|
||||||
float getHeight() const;
|
float getHeight() const;
|
||||||
|
|
||||||
void poke(ModelCollisionInfo& collision);
|
/// \param collision a data structure for storing info about collisions against Models
|
||||||
|
/// \return true if the collision affects the Avatar models
|
||||||
|
bool poke(ModelCollisionInfo& collision);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateCollisionFlags();
|
void updateCollisionFlags();
|
||||||
|
|
|
@ -224,9 +224,9 @@ void Hand::updateCollisions() {
|
||||||
}
|
}
|
||||||
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
|
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
|
||||||
for (size_t j = 0; j < collisions.size(); ++j) {
|
for (size_t j = 0; j < collisions.size(); ++j) {
|
||||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
if (!avatar->poke(collisions[j])) {
|
||||||
// TODO: Andrew to poke avatar using collision info
|
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||||
avatar->poke(collisions[j]);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -552,6 +552,9 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& position, int last
|
||||||
glm::vec3 relativePosition = position - _translation;
|
glm::vec3 relativePosition = position - _translation;
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
const QVector<int>& freeLineage = geometry.joints.at(jointIndex).freeLineage;
|
const QVector<int>& freeLineage = geometry.joints.at(jointIndex).freeLineage;
|
||||||
|
if (freeLineage.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (lastFreeIndex == -1) {
|
if (lastFreeIndex == -1) {
|
||||||
lastFreeIndex = freeLineage.last();
|
lastFreeIndex = freeLineage.last();
|
||||||
}
|
}
|
||||||
|
@ -710,6 +713,37 @@ void Model::renderCollisionProxies(float alpha) {
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Model::poke(ModelCollisionInfo& collision) {
|
||||||
|
// This needs work. At the moment it can wiggle joints that are free to move (such as arms)
|
||||||
|
// but unmovable joints (such as torso) cannot be influenced at all.
|
||||||
|
glm::vec3 jointPosition(0.f);
|
||||||
|
if (getJointPosition(collision._jointIndex, jointPosition)) {
|
||||||
|
int jointIndex = collision._jointIndex;
|
||||||
|
const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex];
|
||||||
|
if (joint.parentIndex != -1) {
|
||||||
|
// compute the approximate distance (travel) that the joint needs to move
|
||||||
|
glm::vec3 start;
|
||||||
|
getJointPosition(joint.parentIndex, start);
|
||||||
|
glm::vec3 contactPoint = collision._contactPoint - start;
|
||||||
|
glm::vec3 penetrationEnd = contactPoint + collision._penetration;
|
||||||
|
glm::vec3 axis = glm::cross(contactPoint, penetrationEnd);
|
||||||
|
float travel = glm::length(axis);
|
||||||
|
const float MIN_TRAVEL = 1.0e-8f;
|
||||||
|
if (travel > MIN_TRAVEL) {
|
||||||
|
// compute the new position of the joint
|
||||||
|
float angle = asinf(travel / (glm::length(contactPoint) * glm::length(penetrationEnd)));
|
||||||
|
axis = glm::normalize(axis);
|
||||||
|
glm::vec3 end;
|
||||||
|
getJointPosition(jointIndex, end);
|
||||||
|
glm::vec3 newEnd = start + glm::angleAxis(glm::degrees(angle), axis) * (end - start);
|
||||||
|
// try to move it
|
||||||
|
return setJointPosition(jointIndex, newEnd, -1, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Model::deleteGeometry() {
|
void Model::deleteGeometry() {
|
||||||
foreach (Model* attachment, _attachments) {
|
foreach (Model* attachment, _attachments) {
|
||||||
delete attachment;
|
delete attachment;
|
||||||
|
|
|
@ -164,6 +164,10 @@ public:
|
||||||
|
|
||||||
void renderCollisionProxies(float alpha);
|
void renderCollisionProxies(float alpha);
|
||||||
|
|
||||||
|
/// \param collisionInfo info about the collision
|
||||||
|
/// \return true if collision affects the Model
|
||||||
|
bool poke(ModelCollisionInfo& collisionInfo);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QSharedPointer<NetworkGeometry> _geometry;
|
QSharedPointer<NetworkGeometry> _geometry;
|
||||||
|
|
Loading…
Reference in a new issue