mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
Working on plane collisions, pushing back camera from intersecting avatars.
This commit is contained in:
parent
89c2812551
commit
9f58264cb6
9 changed files with 201 additions and 0 deletions
|
@ -522,6 +522,19 @@ void Application::paintGL() {
|
|||
_myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation());
|
||||
|
||||
// push camera out of any intersecting avatars
|
||||
float pushback = 0.0f;
|
||||
foreach (const AvatarSharedPointer& avatarData, _avatarManager.getAvatarHash()) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarData.data());
|
||||
const float RADIUS_MULTIPLIER = 2.0f;
|
||||
CollisionList collisions(4);
|
||||
if (!avatar->isMyAvatar() && avatar->findSphereCollisions(_myCamera.getTargetPosition(),
|
||||
_myCamera.getNearClip() * RADIUS_MULTIPLIER, collisions)) {
|
||||
for (int i = 0; i < collisions.size(); i++) {
|
||||
collisions.getCollision(i)->_penetration;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||
_myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing
|
||||
_myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition());
|
||||
|
|
|
@ -522,6 +522,11 @@ bool Avatar::findSphereCollisions(const glm::vec3& penetratorCenter, float penet
|
|||
//return getHead()->getFaceModel().findSphereCollisions(penetratorCenter, penetratorRadius, collisions);
|
||||
}
|
||||
|
||||
bool Avatar::findPlaneCollisions(const glm::vec4& plane, CollisionList& collisions) {
|
||||
return _skeletonModel.findPlaneCollisions(plane, collisions) ||
|
||||
getHead()->getFaceModel().findPlaneCollisions(plane, collisions);
|
||||
}
|
||||
|
||||
void Avatar::updateShapePositions() {
|
||||
_skeletonModel.updateShapePositions();
|
||||
Model& headModel = getHead()->getFaceModel();
|
||||
|
|
|
@ -119,6 +119,12 @@ public:
|
|||
bool findSphereCollisions(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
CollisionList& collisions, int skeletonSkipIndex = -1);
|
||||
|
||||
/// Checks for penetration between the described plane and the avatar.
|
||||
/// \param plane the penetration plane
|
||||
/// \param collisions[out] a list to which collisions get appended
|
||||
/// \return whether or not the plane penetrated
|
||||
bool findPlaneCollisions(const glm::vec4& plane, CollisionList& collisions);
|
||||
|
||||
/// Checks for collision between the a spherical particle and the avatar (including paddle hands)
|
||||
/// \param collisionCenter the center of particle's bounding sphere
|
||||
/// \param collisionRadius the radius of particle's bounding sphere
|
||||
|
|
|
@ -634,6 +634,21 @@ bool Model::findSphereCollisions(const glm::vec3& sphereCenter, float sphereRadi
|
|||
return collided;
|
||||
}
|
||||
|
||||
bool Model::findPlaneCollisions(const glm::vec4& plane, CollisionList& collisions) {
|
||||
bool collided = false;
|
||||
PlaneShape planeShape(plane);
|
||||
for (int i = 0; i < _jointShapes.size(); i++) {
|
||||
if (ShapeCollider::shapeShape(&planeShape, _jointShapes[i], collisions)) {
|
||||
CollisionInfo* collision = collisions.getLastCollision();
|
||||
collision->_type = MODEL_COLLISION;
|
||||
collision->_data = (void*)(this);
|
||||
collision->_flags = i;
|
||||
collided = true;
|
||||
}
|
||||
}
|
||||
return collided;
|
||||
}
|
||||
|
||||
class Blender : public QRunnable {
|
||||
public:
|
||||
|
||||
|
|
|
@ -176,6 +176,8 @@ public:
|
|||
|
||||
bool findSphereCollisions(const glm::vec3& penetratorCenter, float penetratorRadius,
|
||||
CollisionList& collisions, int skipIndex = -1);
|
||||
|
||||
bool findPlaneCollisions(const glm::vec4& plane, CollisionList& collisions);
|
||||
|
||||
/// \param collision details about the collisions
|
||||
/// \return true if the collision is against a moveable joint
|
||||
|
|
30
libraries/shared/src/PlaneShape.h
Normal file
30
libraries/shared/src/PlaneShape.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// PlaneShape.h
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Andrzej Kapolka on 4/9/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_PlaneShape_h
|
||||
#define hifi_PlaneShape_h
|
||||
|
||||
#include "Shape.h"
|
||||
|
||||
class PlaneShape : public Shape {
|
||||
public:
|
||||
PlaneShape() : Shape(Shape::PLANE_SHAPE) {}
|
||||
|
||||
PlaneShape(const glm::vec4& coefficients) : Shape(Shape::PLANE_SHAPE), _coefficients(coefficients) { }
|
||||
|
||||
const glm::vec4& getCoefficients() const { return _coefficients; }
|
||||
|
||||
private:
|
||||
|
||||
glm::vec4 _coefficients;
|
||||
};
|
||||
|
||||
#endif // hifi_PlaneShape_h
|
|
@ -22,6 +22,7 @@ public:
|
|||
UNKNOWN_SHAPE = 0,
|
||||
SPHERE_SHAPE,
|
||||
CAPSULE_SHAPE,
|
||||
PLANE_SHAPE,
|
||||
BOX_SHAPE,
|
||||
LIST_SHAPE
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include "GeometryUtil.h"
|
||||
#include "ShapeCollider.h"
|
||||
|
||||
// NOTE:
|
||||
|
@ -33,6 +34,8 @@ bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisi
|
|||
return sphereSphere(sphereA, static_cast<const SphereShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::CAPSULE_SHAPE) {
|
||||
return sphereCapsule(sphereA, static_cast<const CapsuleShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::PLANE_SHAPE) {
|
||||
return spherePlane(sphereA, static_cast<const PlaneShape*>(shapeB), collisions);
|
||||
}
|
||||
} else if (typeA == Shape::CAPSULE_SHAPE) {
|
||||
const CapsuleShape* capsuleA = static_cast<const CapsuleShape*>(shapeA);
|
||||
|
@ -40,6 +43,17 @@ bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisi
|
|||
return capsuleSphere(capsuleA, static_cast<const SphereShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::CAPSULE_SHAPE) {
|
||||
return capsuleCapsule(capsuleA, static_cast<const CapsuleShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::PLANE_SHAPE) {
|
||||
return capsulePlane(capsuleA, static_cast<const PlaneShape*>(shapeB), collisions);
|
||||
}
|
||||
} else if (typeA == Shape::PLANE_SHAPE) {
|
||||
const PlaneShape* planeA = static_cast<const PlaneShape*>(shapeA);
|
||||
if (typeB == Shape::SPHERE_SHAPE) {
|
||||
return planeSphere(planeA, static_cast<const SphereShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::CAPSULE_SHAPE) {
|
||||
return planeCapsule(planeA, static_cast<const CapsuleShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::PLANE_SHAPE) {
|
||||
return planePlane(planeA, static_cast<const PlaneShape*>(shapeB), collisions);
|
||||
}
|
||||
} else if (typeA == Shape::LIST_SHAPE) {
|
||||
const ListShape* listA = static_cast<const ListShape*>(shapeA);
|
||||
|
@ -47,6 +61,8 @@ bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisi
|
|||
return listSphere(listA, static_cast<const SphereShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::CAPSULE_SHAPE) {
|
||||
return listCapsule(listA, static_cast<const CapsuleShape*>(shapeB), collisions);
|
||||
} else if (typeB == Shape::PLANE_SHAPE) {
|
||||
return listPlane(listA, static_cast<const PlaneShape*>(shapeB), collisions);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -143,6 +159,20 @@ bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB, Col
|
|||
return false;
|
||||
}
|
||||
|
||||
bool spherePlane(const SphereShape* sphereA, const PlaneShape* planeB, CollisionList& collisions) {
|
||||
glm::vec3 penetration;
|
||||
if (findSpherePlanePenetration(sphereA->getPosition(), sphereA->getRadius(), planeB->getCoefficients(), penetration)) {
|
||||
CollisionInfo* collision = collisions.getNewCollision();
|
||||
if (!collision) {
|
||||
return false; // collision list is full
|
||||
}
|
||||
collision->_penetration = penetration;
|
||||
collision->_contactPoint = glm::vec3();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB, CollisionList& collisions) {
|
||||
// find sphereB's closest approach to axis of capsuleA
|
||||
glm::vec3 AB = capsuleA->getPosition() - sphereB->getPosition();
|
||||
|
@ -349,6 +379,22 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool capsulePlane(const CapsuleShape* capsuleA, const PlaneShape* planeB, CollisionList& collisions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool planeSphere(const PlaneShape* planeA, const SphereShape* sphereB, CollisionList& collisions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool planeCapsule(const PlaneShape* planeA, const CapsuleShape* capsuleB, CollisionList& collisions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool planePlane(const PlaneShape* planeA, const PlaneShape* planeB, CollisionList& collisions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sphereList(const SphereShape* sphereA, const ListShape* listB, CollisionList& collisions) {
|
||||
bool touching = false;
|
||||
for (int i = 0; i < listB->size() && !collisions.isFull(); ++i) {
|
||||
|
@ -358,6 +404,8 @@ bool sphereList(const SphereShape* sphereA, const ListShape* listB, CollisionLis
|
|||
touching = sphereSphere(sphereA, static_cast<const SphereShape*>(subShape), collisions) || touching;
|
||||
} else if (subType == Shape::CAPSULE_SHAPE) {
|
||||
touching = sphereCapsule(sphereA, static_cast<const CapsuleShape*>(subShape), collisions) || touching;
|
||||
} else if (subType == Shape::PLANE_SHAPE) {
|
||||
touching = spherePlane(sphereA, static_cast<const PlaneShape*>(subShape), collisions) || touching;
|
||||
}
|
||||
}
|
||||
return touching;
|
||||
|
@ -372,6 +420,24 @@ bool capsuleList(const CapsuleShape* capsuleA, const ListShape* listB, Collision
|
|||
touching = capsuleSphere(capsuleA, static_cast<const SphereShape*>(subShape), collisions) || touching;
|
||||
} else if (subType == Shape::CAPSULE_SHAPE) {
|
||||
touching = capsuleCapsule(capsuleA, static_cast<const CapsuleShape*>(subShape), collisions) || touching;
|
||||
} else if (subType == Shape::PLANE_SHAPE) {
|
||||
touching = capsulePlane(capsuleA, static_cast<const PlaneShape*>(subShape), collisions) || touching;
|
||||
}
|
||||
}
|
||||
return touching;
|
||||
}
|
||||
|
||||
bool planeList(const PlaneShape* planeA, const ListShape* listB, CollisionList& collisions) {
|
||||
bool touching = false;
|
||||
for (int i = 0; i < listB->size() && !collisions.isFull(); ++i) {
|
||||
const Shape* subShape = listB->getSubShape(i);
|
||||
int subType = subShape->getType();
|
||||
if (subType == Shape::SPHERE_SHAPE) {
|
||||
touching = planeSphere(planeA, static_cast<const SphereShape*>(subShape), collisions) || touching;
|
||||
} else if (subType == Shape::CAPSULE_SHAPE) {
|
||||
touching = planeCapsule(planeA, static_cast<const CapsuleShape*>(subShape), collisions) || touching;
|
||||
} else if (subType == Shape::PLANE_SHAPE) {
|
||||
touching = planePlane(planeA, static_cast<const PlaneShape*>(subShape), collisions) || touching;
|
||||
}
|
||||
}
|
||||
return touching;
|
||||
|
@ -386,6 +452,8 @@ bool listSphere(const ListShape* listA, const SphereShape* sphereB, CollisionLis
|
|||
touching = sphereSphere(static_cast<const SphereShape*>(subShape), sphereB, collisions) || touching;
|
||||
} else if (subType == Shape::CAPSULE_SHAPE) {
|
||||
touching = capsuleSphere(static_cast<const CapsuleShape*>(subShape), sphereB, collisions) || touching;
|
||||
} else if (subType == Shape::PLANE_SHAPE) {
|
||||
touching = planeSphere(static_cast<const PlaneShape*>(subShape), sphereB, collisions) || touching;
|
||||
}
|
||||
}
|
||||
return touching;
|
||||
|
@ -400,6 +468,24 @@ bool listCapsule(const ListShape* listA, const CapsuleShape* capsuleB, Collision
|
|||
touching = sphereCapsule(static_cast<const SphereShape*>(subShape), capsuleB, collisions) || touching;
|
||||
} else if (subType == Shape::CAPSULE_SHAPE) {
|
||||
touching = capsuleCapsule(static_cast<const CapsuleShape*>(subShape), capsuleB, collisions) || touching;
|
||||
} else if (subType == Shape::PLANE_SHAPE) {
|
||||
touching = planeCapsule(static_cast<const PlaneShape*>(subShape), capsuleB, collisions) || touching;
|
||||
}
|
||||
}
|
||||
return touching;
|
||||
}
|
||||
|
||||
bool listPlane(const ListShape* listA, const PlaneShape* planeB, CollisionList& collisions) {
|
||||
bool touching = false;
|
||||
for (int i = 0; i < listA->size() && !collisions.isFull(); ++i) {
|
||||
const Shape* subShape = listA->getSubShape(i);
|
||||
int subType = subShape->getType();
|
||||
if (subType == Shape::SPHERE_SHAPE) {
|
||||
touching = spherePlane(static_cast<const SphereShape*>(subShape), planeB, collisions) || touching;
|
||||
} else if (subType == Shape::CAPSULE_SHAPE) {
|
||||
touching = capsulePlane(static_cast<const CapsuleShape*>(subShape), planeB, collisions) || touching;
|
||||
} else if (subType == Shape::PLANE_SHAPE) {
|
||||
touching = planePlane(static_cast<const PlaneShape*>(subShape), planeB, collisions) || touching;
|
||||
}
|
||||
}
|
||||
return touching;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "CapsuleShape.h"
|
||||
#include "CollisionInfo.h"
|
||||
#include "ListShape.h"
|
||||
#include "PlaneShape.h"
|
||||
#include "SharedUtil.h"
|
||||
#include "SphereShape.h"
|
||||
|
||||
|
@ -38,6 +39,12 @@ namespace ShapeCollider {
|
|||
/// \return true if shapes collide
|
||||
bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB, CollisionList& collisions);
|
||||
|
||||
/// \param sphereA pointer to first shape
|
||||
/// \param planeB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
/// \return true if shapes collide
|
||||
bool spherePlane(const SphereShape* sphereA, const PlaneShape* planeB, CollisionList& collisions);
|
||||
|
||||
/// \param capsuleA pointer to first shape
|
||||
/// \param sphereB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
|
@ -50,6 +57,30 @@ namespace ShapeCollider {
|
|||
/// \return true if shapes collide
|
||||
bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB, CollisionList& collisions);
|
||||
|
||||
/// \param capsuleA pointer to first shape
|
||||
/// \param planeB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
/// \return true if shapes collide
|
||||
bool capsulePlane(const CapsuleShape* capsuleA, const PlaneShape* planeB, CollisionList& collisions);
|
||||
|
||||
/// \param planeA pointer to first shape
|
||||
/// \param sphereB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
/// \return true if shapes collide
|
||||
bool planeSphere(const PlaneShape* planeA, const SphereShape* sphereB, CollisionList& collisions);
|
||||
|
||||
/// \param planeA pointer to first shape
|
||||
/// \param capsuleB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
/// \return true if shapes collide
|
||||
bool planeCapsule(const PlaneShape* planeA, const CapsuleShape* capsuleB, CollisionList& collisions);
|
||||
|
||||
/// \param planeA pointer to first shape
|
||||
/// \param planeB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
/// \return true if shapes collide
|
||||
bool planePlane(const PlaneShape* planeA, const PlaneShape* planeB, CollisionList& collisions);
|
||||
|
||||
/// \param sphereA pointer to first shape
|
||||
/// \param listB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
|
@ -62,6 +93,12 @@ namespace ShapeCollider {
|
|||
/// \return true if shapes collide
|
||||
bool capsuleList(const CapsuleShape* capsuleA, const ListShape* listB, CollisionList& collisions);
|
||||
|
||||
/// \param planeA pointer to first shape
|
||||
/// \param listB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
/// \return true if shapes collide
|
||||
bool planeList(const PlaneShape* planeA, const ListShape* listB, CollisionList& collisions);
|
||||
|
||||
/// \param listA pointer to first shape
|
||||
/// \param sphereB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
|
@ -74,6 +111,12 @@ namespace ShapeCollider {
|
|||
/// \return true if shapes collide
|
||||
bool listCapsule(const ListShape* listA, const CapsuleShape* capsuleB, CollisionList& collisions);
|
||||
|
||||
/// \param listA pointer to first shape
|
||||
/// \param planeB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
/// \return true if shapes collide
|
||||
bool listPlane(const ListShape* listA, const PlaneShape* planeB, CollisionList& collisions);
|
||||
|
||||
/// \param listA pointer to first shape
|
||||
/// \param capsuleB pointer to second shape
|
||||
/// \param[out] collisions where to append collision details
|
||||
|
|
Loading…
Reference in a new issue