Merge pull request #2641 from AndrewMeadows/scripting

avatar-avatar collisions are now exposed to JS
This commit is contained in:
Philip Rosedale 2014-04-10 09:20:29 -07:00
commit 67c8fd5630
10 changed files with 178 additions and 82 deletions

View file

@ -0,0 +1,68 @@
//
// avatarCollision.js
// examples
//
// Created by Andrew Meadows on 2014-04-09
// Copyright 2014 High Fidelity, Inc.
//
// Play a sound on collisions with your avatar
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var SOUND_TRIGGER_CLEAR = 1000; // milliseconds
var SOUND_TRIGGER_DELAY = 200; // milliseconds
var soundExpiry = 0;
var DateObj = new Date();
var audioOptions = new AudioInjectionOptions();
audioOptions.volume = 0.5;
audioOptions.position = { x: 0, y: 0, z: 0 };
var hitSounds = new Array();
hitSounds[0] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit1.raw");
hitSounds[1] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit2.raw");
hitSounds[2] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit3.raw");
hitSounds[3] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit4.raw");
hitSounds[4] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit5.raw");
hitSounds[5] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit6.raw");
hitSounds[6] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit7.raw");
hitSounds[7] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit8.raw");
hitSounds[8] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit9.raw");
hitSounds[9] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit10.raw");
hitSounds[10] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit11.raw");
hitSounds[11] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit12.raw");
hitSounds[12] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit13.raw");
hitSounds[13] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit14.raw");
hitSounds[14] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit15.raw");
hitSounds[15] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit16.raw");
hitSounds[16] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit17.raw");
hitSounds[17] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit18.raw");
hitSounds[18] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit19.raw");
hitSounds[19] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit20.raw");
hitSounds[20] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit21.raw");
hitSounds[21] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit22.raw");
function playHitSound(mySessionID, theirSessionID, collision) {
var now = new Date();
var msec = now.getTime();
if (msec > soundExpiry) {
// this is a new contact --> play a new sound
var soundIndex = Math.floor((Math.random() * hitSounds.length) % hitSounds.length);
audioOptions.position = collision.contactPoint;
Audio.playSound(hitSounds[soundIndex], audioOptions);
// bump the expiry
soundExpiry = msec + SOUND_TRIGGER_CLEAR;
// log the collision info
Uuid.print("my sessionID = ", mySessionID);
Uuid.print(" their sessionID = ", theirSessionID);
Vec3.print(" penetration = ", collision.penetration);
Vec3.print(" contactPoint = ", collision.contactPoint);
} else {
// this is a recurring contact --> continue to delay sound trigger
soundExpiry = msec + SOUND_TRIGGER_DELAY;
}
}
MyAvatar.collisionWithAvatar.connect(playHitSound);

View file

@ -233,22 +233,22 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
// quick check before falling into the code below:
// (a 10 degree breadth of an almost 2 meter avatar kicks in at about 12m)
const float MIN_VOICE_SPHERE_DISTANCE = 12.f;
const float MIN_VOICE_SPHERE_DISTANCE = 12.0f;
if (distanceToTarget > MIN_VOICE_SPHERE_DISTANCE) {
// render voice intensity sphere for avatars that are farther away
const float MAX_SPHERE_ANGLE = 10.f * RADIANS_PER_DEGREE;
const float MIN_SPHERE_ANGLE = 1.f * RADIANS_PER_DEGREE;
const float MAX_SPHERE_ANGLE = 10.0f * RADIANS_PER_DEGREE;
const float MIN_SPHERE_ANGLE = 1.0f * RADIANS_PER_DEGREE;
const float MIN_SPHERE_SIZE = 0.01f;
const float SPHERE_LOUDNESS_SCALING = 0.0005f;
const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f };
float height = getSkeletonHeight();
glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f;
glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.0f;
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING;
if (renderMode == NORMAL_RENDER_MODE && (sphereRadius > MIN_SPHERE_SIZE) &&
(angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) {
glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE);
glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.0f - angle / MAX_SPHERE_ANGLE);
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z);
glScalef(height, height, height);
@ -280,9 +280,9 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
glm::vec3 chatAxis = glm::axis(chatRotation);
glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z);
glColor3f(0.f, 0.8f, 0.f);
glRotatef(180.f, 0.f, 1.f, 0.f);
glRotatef(180.f, 0.f, 0.f, 1.f);
glColor3f(0.0f, 0.8f, 0.0f);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
glRotatef(180.0f, 0.0f, 0.0f, 1.0f);
glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f);
glDisable(GL_LIGHTING);
@ -298,7 +298,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
_chatMessage[lastIndex] = '\0';
textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str());
_chatMessage[lastIndex] = lastChar;
glColor3f(0.f, 1.f, 0.f);
glColor3f(0.0f, 1.0f, 0.0f);
textRenderer(CHAT)->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex);
}
glEnable(GL_LIGHTING);
@ -550,7 +550,7 @@ bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float parti
const PalmData* palm = handData->getPalm(i);
if (palm && palm->hasPaddle()) {
// create a disk collision proxy where the hand is
glm::vec3 fingerAxis(0.f);
glm::vec3 fingerAxis(0.0f);
for (size_t f = 0; f < palm->getNumFingers(); ++f) {
const FingerData& finger = (palm->getFingers())[f];
if (finger.isActive()) {
@ -692,8 +692,8 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
glm::vec3 perpCos = glm::normalize(glm::cross(axis, perpSin));
perpSin = glm::cross(perpCos, axis);
float anglea = 0.f;
float angleb = 0.f;
float anglea = 0.0f;
float angleb = 0.0f;
for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) {
@ -743,8 +743,8 @@ void Avatar::updateCollisionFlags() {
void Avatar::setScale(float scale) {
_scale = scale;
if (_targetScale * (1.f - RESCALING_TOLERANCE) < _scale &&
_scale < _targetScale * (1.f + RESCALING_TOLERANCE)) {
if (_targetScale * (1.0f - RESCALING_TOLERANCE) < _scale &&
_scale < _targetScale * (1.0f + RESCALING_TOLERANCE)) {
_scale = _targetScale;
}
}

View file

@ -64,7 +64,7 @@ enum ScreenTintLayer {
// 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
const glm::vec3 START_LOCATION(0.485f * TREE_SCALE, 0.f, 0.5f * TREE_SCALE);
const glm::vec3 START_LOCATION(0.485f * TREE_SCALE, 0.0f, 0.5f * TREE_SCALE);
class Texture;
@ -143,8 +143,6 @@ public:
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
/// \return true if we expect the avatar would move as a result of the collision
bool collisionWouldMoveAvatar(CollisionInfo& collision) const;
@ -157,6 +155,9 @@ public:
public slots:
void updateCollisionFlags();
signals:
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
protected:
SkeletonModel _skeletonModel;
float _bodyYawDelta;

View file

@ -163,6 +163,11 @@ void Hand::collideAgainstAvatar(Avatar* avatar, bool isMyHand) {
// TODO: submit collision info to MyAvatar which should lean accordingly
averageContactPoint /= (float)handCollisions.size();
avatar->applyCollision(averageContactPoint, totalPenetration);
CollisionInfo collision;
collision._penetration = totalPenetration;
collision._contactPoint = averageContactPoint;
emit avatar->collisionWithAvatar(avatar->getSessionUUID(), _owningAvatar->getSessionUUID(), collision);
}
}
}

View file

@ -896,8 +896,7 @@ bool findAvatarAvatarPenetration(const glm::vec3 positionA, float radiusA, float
return false;
}
static CollisionList bodyCollisions(16);
const float BODY_COLLISION_RESOLVE_TIMESCALE = 0.5f; // seconds
const float BODY_COLLISION_RESOLUTION_TIMESCALE = 0.5f; // seconds
void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
// Reset detector for nearest avatar
@ -910,7 +909,7 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
updateShapePositions();
float myBoundingRadius = getBoundingRadius();
const float BODY_COLLISION_RESOLVE_FACTOR = deltaTime / BODY_COLLISION_RESOLVE_TIMESCALE;
const float BODY_COLLISION_RESOLUTION_FACTOR = deltaTime / BODY_COLLISION_RESOLUTION_TIMESCALE;
foreach (const AvatarSharedPointer& avatarPointer, avatars) {
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
@ -930,26 +929,19 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
_skeletonModel.getBodyShapes(myShapes);
QVector<const Shape*> theirShapes;
avatar->getSkeletonModel().getBodyShapes(theirShapes);
bodyCollisions.clear();
// TODO: add method to ShapeCollider for colliding lists of shapes
foreach (const Shape* myShape, myShapes) {
foreach (const Shape* theirShape, theirShapes) {
ShapeCollider::shapeShape(myShape, theirShape, bodyCollisions);
CollisionInfo collision;
if (ShapeCollider::collideShapesCoarse(myShapes, theirShapes, collision)) {
if (glm::length2(collision._penetration) > EPSILON) {
setPosition(getPosition() - BODY_COLLISION_RESOLUTION_FACTOR * collision._penetration);
_lastBodyPenetration += collision._penetration;
emit collisionWithAvatar(getSessionUUID(), avatar->getSessionUUID(), collision);
}
}
glm::vec3 totalPenetration(0.0f);
for (int j = 0; j < bodyCollisions.size(); ++j) {
CollisionInfo* collision = bodyCollisions.getCollision(j);
totalPenetration = addPenetrations(totalPenetration, collision->_penetration);
}
if (glm::length2(totalPenetration) > EPSILON) {
setPosition(getPosition() - BODY_COLLISION_RESOLVE_FACTOR * totalPenetration);
}
_lastBodyPenetration += totalPenetration;
// collide our hands against them
// TODO: make this work when we can figure out when the other avatar won't yeild
// (for example, we're colling against their chest or leg)
// (for example, we're colliding against their chest or leg)
//getHand()->collideAgainstAvatar(avatar, true);
// collide their hands against us

View file

@ -595,7 +595,7 @@ bool Model::findCollisions(const QVector<const Shape*> shapes, CollisionList& co
const Shape* theirShape = shapes[i];
for (int j = 0; j < _jointShapes.size(); ++j) {
const Shape* ourShape = _jointShapes[j];
if (ShapeCollider::shapeShape(theirShape, ourShape, collisions)) {
if (ShapeCollider::collideShapes(theirShape, ourShape, collisions)) {
collided = true;
}
}
@ -622,7 +622,7 @@ bool Model::findSphereCollisions(const glm::vec3& sphereCenter, float sphereRadi
} while (ancestorIndex != -1);
}
}
if (ShapeCollider::shapeShape(&sphere, _jointShapes[i], collisions)) {
if (ShapeCollider::collideShapes(&sphere, _jointShapes[i], collisions)) {
CollisionInfo* collision = collisions.getLastCollision();
collision->_type = MODEL_COLLISION;
collision->_data = (void*)(this);

View file

@ -116,7 +116,6 @@ private:
static VoxelsScriptingInterface _voxelsScriptingInterface;
static ParticlesScriptingInterface _particlesScriptingInterface;
static int _scriptNumber;
AbstractControllerScriptingInterface* _controllerScriptingInterface;
AudioScriptingInterface _audioScriptingInterface;

View file

@ -13,6 +13,7 @@
#include <glm/gtx/norm.hpp>
#include "GeometryUtil.h"
#include "ShapeCollider.h"
// NOTE:
@ -22,7 +23,7 @@
namespace ShapeCollider {
bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisions) {
bool collideShapes(const Shape* shapeA, const Shape* shapeB, CollisionList& collisions) {
// ATM we only have two shape types so we just check every case.
// TODO: make a fast lookup for correct method
int typeA = shapeA->getType();
@ -52,6 +53,30 @@ bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisi
return false;
}
static CollisionList tempCollisions(32);
bool collideShapesCoarse(const QVector<const Shape*>& shapesA, const QVector<const Shape*>& shapesB, CollisionInfo& collision) {
tempCollisions.clear();
foreach (const Shape* shapeA, shapesA) {
foreach (const Shape* shapeB, shapesB) {
ShapeCollider::collideShapes(shapeA, shapeB, tempCollisions);
}
}
if (tempCollisions.size() > 0) {
glm::vec3 totalPenetration(0.0f);
glm::vec3 averageContactPoint(0.0f);
for (int j = 0; j < tempCollisions.size(); ++j) {
CollisionInfo* c = tempCollisions.getCollision(j);
totalPenetration = addPenetrations(totalPenetration, c->_penetration);
averageContactPoint += c->_contactPoint;
}
collision._penetration = totalPenetration;
collision._contactPoint = averageContactPoint / (float)(tempCollisions.size());
return true;
}
return false;
}
bool sphereSphere(const SphereShape* sphereA, const SphereShape* sphereB, CollisionList& collisions) {
glm::vec3 BA = sphereB->getPosition() - sphereA->getPosition();
float distanceSquared = glm::dot(BA, BA);
@ -61,7 +86,7 @@ bool sphereSphere(const SphereShape* sphereA, const SphereShape* sphereB, Collis
float distance = sqrtf(distanceSquared);
if (distance < EPSILON) {
// the spheres are on top of each other, so we pick an arbitrary penetration direction
BA = glm::vec3(0.f, 1.f, 0.f);
BA = glm::vec3(0.0f, 1.0f, 0.0f);
distance = totalRadius;
} else {
BA /= distance;
@ -96,7 +121,7 @@ bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB, Col
}
if (absAxialDistance > capsuleB->getHalfHeight()) {
// sphere hits capsule on a cap --> recompute radialAxis to point from spherA to cap center
float sign = (axialDistance > 0.f) ? 1.f : -1.f;
float sign = (axialDistance > 0.0f) ? 1.0f : -1.0f;
radialAxis = BA + (sign * capsuleB->getHalfHeight()) * capsuleAxis;
radialDistance2 = glm::length2(radialAxis);
if (radialDistance2 > totalRadius2) {
@ -128,12 +153,12 @@ bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB, Col
return false;
}
// ... but still defined for the cap case
if (axialDistance < 0.f) {
if (axialDistance < 0.0f) {
// we're hitting the start cap, so we negate the capsuleAxis
capsuleAxis *= -1;
}
// penetration points from A into B
float sign = (axialDistance > 0.f) ? -1.f : 1.f;
float sign = (axialDistance > 0.0f) ? -1.0f : 1.0f;
collision->_penetration = (sign * (totalRadius + capsuleB->getHalfHeight() - absAxialDistance)) * capsuleAxis;
// contactPoint is on surface of sphereA
collision->_contactPoint = sphereA->getPosition() + (sign * sphereA->getRadius()) * capsuleAxis;
@ -166,7 +191,7 @@ bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB, Col
if (absAxialDistance > capsuleA->getHalfHeight()) {
// sphere hits capsule on a cap
// --> recompute radialAxis and closestApproach
float sign = (axialDistance > 0.f) ? 1.f : -1.f;
float sign = (axialDistance > 0.0f) ? 1.0f : -1.0f;
closestApproach = capsuleA->getPosition() + (sign * capsuleA->getHalfHeight()) * capsuleAxis;
radialAxis = closestApproach - sphereB->getPosition();
radialDistance2 = glm::length2(radialAxis);
@ -199,11 +224,11 @@ bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB, Col
return false;
}
// ... but still defined for the cap case
if (axialDistance < 0.f) {
if (axialDistance < 0.0f) {
// we're hitting the start cap, so we negate the capsuleAxis
capsuleAxis *= -1;
}
float sign = (axialDistance > 0.f) ? 1.f : -1.f;
float sign = (axialDistance > 0.0f) ? 1.0f : -1.0f;
collision->_penetration = (sign * (totalRadius + capsuleA->getHalfHeight() - absAxialDistance)) * capsuleAxis;
// contactPoint is on surface of sphereA
collision->_contactPoint = closestApproach + (sign * capsuleA->getRadius()) * capsuleAxis;
@ -226,7 +251,7 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
// d = [(B - A) . (a - (a.b)b)] / (1 - (a.b)^2)
float aDotB = glm::dot(axisA, axisB);
float denominator = 1.f - aDotB * aDotB;
float denominator = 1.0f - aDotB * aDotB;
float totalRadius = capsuleA->getRadius() + capsuleB->getRadius();
if (denominator > EPSILON) {
// distances to points of closest approach
@ -236,12 +261,12 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
// clamp the distances to the ends of the capsule line segments
float absDistanceA = fabs(distanceA);
if (absDistanceA > capsuleA->getHalfHeight() + capsuleA->getRadius()) {
float signA = distanceA < 0.f ? -1.f : 1.f;
float signA = distanceA < 0.0f ? -1.0f : 1.0f;
distanceA = signA * capsuleA->getHalfHeight();
}
float absDistanceB = fabs(distanceB);
if (absDistanceB > capsuleB->getHalfHeight() + capsuleB->getRadius()) {
float signB = distanceB < 0.f ? -1.f : 1.f;
float signB = distanceB < 0.0f ? -1.0f : 1.0f;
distanceB = signB * capsuleB->getHalfHeight();
}
@ -268,7 +293,7 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
{
// the capsule centers are on top of each other!
// give up on a valid penetration direction and just use the yAxis
BA = glm::vec3(0.f, 1.f, 0.f);
BA = glm::vec3(0.0f, 1.0f, 0.0f);
distance = glm::max(capsuleB->getRadius(), capsuleA->getRadius());
}
} else {
@ -300,7 +325,7 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
float distance = sqrtf(distanceSquared);
if (distance < EPSILON) {
// the spheres are on top of each other, so we pick an arbitrary penetration direction
BA = glm::vec3(0.f, 1.f, 0.f);
BA = glm::vec3(0.0f, 1.0f, 0.0f);
} else {
BA /= distance;
}
@ -410,7 +435,7 @@ bool listList(const ListShape* listA, const ListShape* listB, CollisionList& col
for (int i = 0; i < listA->size() && !collisions.isFull(); ++i) {
const Shape* subShape = listA->getSubShape(i);
for (int j = 0; j < listB->size() && !collisions.isFull(); ++j) {
touching = shapeShape(subShape, listB->getSubShape(j), collisions) || touching;
touching = collideShapes(subShape, listB->getSubShape(j), collisions) || touching;
}
}
return touching;

View file

@ -22,9 +22,15 @@ namespace ShapeCollider {
/// \param shapeA pointer to first shape
/// \param shapeB pointer to second shape
/// \param[out] collisions where to append collision details
/// \param collisions[out] collision details
/// \return true if shapes collide
bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisions);
bool collideShapes(const Shape* shapeA, const Shape* shapeB, CollisionList& collisions);
/// \param shapesA list of shapes
/// \param shapeB list of shapes
/// \param collisions[out] average collision details
/// \return true if any shapes collide
bool collideShapesCoarse(const QVector<const Shape*>& shapesA, const QVector<const Shape*>& shapesB, CollisionInfo& collision);
/// \param sphereA pointer to first shape
/// \param sphereB pointer to second shape

View file

@ -43,7 +43,7 @@ void ShapeColliderTests::sphereMissesSphere() {
// collide A to B...
{
bool touching = ShapeCollider::shapeShape(&sphereA, &sphereB, collisions);
bool touching = ShapeCollider::collideShapes(&sphereA, &sphereB, collisions);
if (touching) {
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphereA and sphereB should NOT touch" << std::endl;
@ -52,7 +52,7 @@ void ShapeColliderTests::sphereMissesSphere() {
// collide B to A...
{
bool touching = ShapeCollider::shapeShape(&sphereB, &sphereA, collisions);
bool touching = ShapeCollider::collideShapes(&sphereB, &sphereA, collisions);
if (touching) {
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphereA and sphereB should NOT touch" << std::endl;
@ -61,7 +61,7 @@ void ShapeColliderTests::sphereMissesSphere() {
// also test shapeShape
{
bool touching = ShapeCollider::shapeShape(&sphereB, &sphereA, collisions);
bool touching = ShapeCollider::collideShapes(&sphereB, &sphereA, collisions);
if (touching) {
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphereA and sphereB should NOT touch" << std::endl;
@ -93,7 +93,7 @@ void ShapeColliderTests::sphereTouchesSphere() {
// collide A to B...
{
bool touching = ShapeCollider::shapeShape(&sphereA, &sphereB, collisions);
bool touching = ShapeCollider::collideShapes(&sphereA, &sphereB, collisions);
if (!touching) {
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphereA and sphereB should touch" << std::endl;
@ -136,7 +136,7 @@ void ShapeColliderTests::sphereTouchesSphere() {
// collide B to A...
{
bool touching = ShapeCollider::shapeShape(&sphereB, &sphereA, collisions);
bool touching = ShapeCollider::collideShapes(&sphereB, &sphereA, collisions);
if (!touching) {
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphereA and sphereB should touch" << std::endl;
@ -199,7 +199,7 @@ void ShapeColliderTests::sphereMissesCapsule() {
sphereA.setPosition(rotation * localPosition + translation);
// sphereA agains capsuleB
if (ShapeCollider::shapeShape(&sphereA, &capsuleB, collisions))
if (ShapeCollider::collideShapes(&sphereA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphere and capsule should NOT touch"
@ -207,7 +207,7 @@ void ShapeColliderTests::sphereMissesCapsule() {
}
// capsuleB against sphereA
if (ShapeCollider::shapeShape(&capsuleB, &sphereA, collisions))
if (ShapeCollider::collideShapes(&capsuleB, &sphereA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphere and capsule should NOT touch"
@ -241,7 +241,7 @@ void ShapeColliderTests::sphereTouchesCapsule() {
{ // sphereA collides with capsuleB's cylindrical wall
sphereA.setPosition(radialOffset * xAxis);
if (!ShapeCollider::shapeShape(&sphereA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&sphereA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphere and capsule should touch"
@ -272,7 +272,7 @@ void ShapeColliderTests::sphereTouchesCapsule() {
}
// capsuleB collides with sphereA
if (!ShapeCollider::shapeShape(&capsuleB, &sphereA, collisions))
if (!ShapeCollider::collideShapes(&capsuleB, &sphereA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and sphere should touch"
@ -308,7 +308,7 @@ void ShapeColliderTests::sphereTouchesCapsule() {
glm::vec3 axialOffset = (halfHeightB + alpha * radiusA + beta * radiusB) * yAxis;
sphereA.setPosition(axialOffset * yAxis);
if (!ShapeCollider::shapeShape(&sphereA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&sphereA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphere and capsule should touch"
@ -339,7 +339,7 @@ void ShapeColliderTests::sphereTouchesCapsule() {
}
// capsuleB collides with sphereA
if (!ShapeCollider::shapeShape(&capsuleB, &sphereA, collisions))
if (!ShapeCollider::collideShapes(&capsuleB, &sphereA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and sphere should touch"
@ -375,7 +375,7 @@ void ShapeColliderTests::sphereTouchesCapsule() {
glm::vec3 axialOffset = - (halfHeightB + alpha * radiusA + beta * radiusB) * yAxis;
sphereA.setPosition(axialOffset * yAxis);
if (!ShapeCollider::shapeShape(&sphereA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&sphereA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: sphere and capsule should touch"
@ -406,7 +406,7 @@ void ShapeColliderTests::sphereTouchesCapsule() {
}
// capsuleB collides with sphereA
if (!ShapeCollider::shapeShape(&capsuleB, &sphereA, collisions))
if (!ShapeCollider::collideShapes(&capsuleB, &sphereA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and sphere should touch"
@ -462,13 +462,13 @@ void ShapeColliderTests::capsuleMissesCapsule() {
// side by side
capsuleB.setPosition((1.01f * totalRadius) * xAxis);
if (ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should NOT touch"
<< std::endl;
}
if (ShapeCollider::shapeShape(&capsuleB, &capsuleA, collisions))
if (ShapeCollider::collideShapes(&capsuleB, &capsuleA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should NOT touch"
@ -477,13 +477,13 @@ void ShapeColliderTests::capsuleMissesCapsule() {
// end to end
capsuleB.setPosition((1.01f * totalHalfLength) * xAxis);
if (ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should NOT touch"
<< std::endl;
}
if (ShapeCollider::shapeShape(&capsuleB, &capsuleA, collisions))
if (ShapeCollider::collideShapes(&capsuleB, &capsuleA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should NOT touch"
@ -494,13 +494,13 @@ void ShapeColliderTests::capsuleMissesCapsule() {
glm::quat rotation = glm::angleAxis(PI_OVER_TWO, zAxis);
capsuleB.setRotation(rotation);
capsuleB.setPosition((1.01f * (totalRadius + capsuleB.getHalfHeight())) * xAxis);
if (ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should NOT touch"
<< std::endl;
}
if (ShapeCollider::shapeShape(&capsuleB, &capsuleA, collisions))
if (ShapeCollider::collideShapes(&capsuleB, &capsuleA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should NOT touch"
@ -532,7 +532,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
{ // side by side
capsuleB.setPosition((0.99f * totalRadius) * xAxis);
if (!ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -540,7 +540,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
} else {
++numCollisions;
}
if (!ShapeCollider::shapeShape(&capsuleB, &capsuleA, collisions))
if (!ShapeCollider::collideShapes(&capsuleB, &capsuleA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -553,7 +553,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
{ // end to end
capsuleB.setPosition((0.99f * totalHalfLength) * yAxis);
if (!ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -561,7 +561,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
} else {
++numCollisions;
}
if (!ShapeCollider::shapeShape(&capsuleB, &capsuleA, collisions))
if (!ShapeCollider::collideShapes(&capsuleB, &capsuleA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -576,7 +576,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
capsuleB.setRotation(rotation);
capsuleB.setPosition((0.99f * (totalRadius + capsuleB.getHalfHeight())) * xAxis);
if (!ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -584,7 +584,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
} else {
++numCollisions;
}
if (!ShapeCollider::shapeShape(&capsuleB, &capsuleA, collisions))
if (!ShapeCollider::collideShapes(&capsuleB, &capsuleA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -602,7 +602,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
capsuleB.setPosition(positionB);
// capsuleA vs capsuleB
if (!ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -631,7 +631,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
}
// capsuleB vs capsuleA
if (!ShapeCollider::shapeShape(&capsuleB, &capsuleA, collisions))
if (!ShapeCollider::collideShapes(&capsuleB, &capsuleA, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"
@ -669,7 +669,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
capsuleB.setPosition(positionB);
// capsuleA vs capsuleB
if (!ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
if (!ShapeCollider::collideShapes(&capsuleA, &capsuleB, collisions))
{
std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: capsule and capsule should touch"