mirror of
https://github.com/overte-org/overte.git
synced 2025-07-15 08:36:45 +02:00
112 lines
3.4 KiB
C++
112 lines
3.4 KiB
C++
//
|
|
// CollisionInfo.cpp
|
|
// libraries/shared/src
|
|
//
|
|
// Created by Andrew Meadows on 02/14/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
|
|
//
|
|
|
|
|
|
|
|
#include "CollisionInfo.h"
|
|
#include "Shape.h"
|
|
#include "SharedUtil.h"
|
|
|
|
CollisionInfo::CollisionInfo() :
|
|
_data(NULL),
|
|
_intData(0),
|
|
_shapeA(NULL),
|
|
_shapeB(NULL),
|
|
_damping(0.0f),
|
|
_elasticity(1.0f),
|
|
_contactPoint(0.0f),
|
|
_penetration(0.0f),
|
|
_addedVelocity(0.0f) {
|
|
}
|
|
|
|
quint64 CollisionInfo::getShapePairKey() const {
|
|
if (_shapeB == NULL || _shapeA == NULL) {
|
|
// zero is an invalid key
|
|
return 0;
|
|
}
|
|
quint32 idA = _shapeA->getID();
|
|
quint32 idB = _shapeB->getID();
|
|
return idA < idB ? ((quint64)idA << 32) + (quint64)idB : ((quint64)idB << 32) + (quint64)idA;
|
|
}
|
|
|
|
CollisionList::CollisionList(int maxSize) :
|
|
_maxSize(maxSize),
|
|
_size(0) {
|
|
_collisions.resize(_maxSize);
|
|
}
|
|
|
|
void CollisionInfo::apply() {
|
|
assert(_shapeA);
|
|
// NOTE: Shape::computeEffectiveMass() has side effects: computes and caches partial Lagrangian coefficients
|
|
Shape* shapeA = const_cast<Shape*>(_shapeA);
|
|
float massA = shapeA->computeEffectiveMass(_penetration, _contactPoint);
|
|
float massB = MAX_SHAPE_MASS;
|
|
float totalMass = massA + massB;
|
|
if (_shapeB) {
|
|
Shape* shapeB = const_cast<Shape*>(_shapeB);
|
|
massB = shapeB->computeEffectiveMass(-_penetration, _contactPoint - _penetration);
|
|
totalMass = massA + massB;
|
|
if (totalMass < EPSILON) {
|
|
massA = massB = 1.0f;
|
|
totalMass = 2.0f;
|
|
}
|
|
// remember that _penetration points from A into B
|
|
shapeB->accumulateDelta(massA / totalMass, _penetration);
|
|
}
|
|
// NOTE: Shape::accumulateDelta() uses the coefficients from previous call to Shape::computeEffectiveMass()
|
|
// remember that _penetration points from A into B
|
|
shapeA->accumulateDelta(massB / totalMass, -_penetration);
|
|
}
|
|
|
|
CollisionInfo* CollisionList::getNewCollision() {
|
|
// return pointer to existing CollisionInfo, or NULL of list is full
|
|
return (_size < _maxSize) ? &(_collisions[_size++]) : NULL;
|
|
}
|
|
|
|
void CollisionList::deleteLastCollision() {
|
|
if (_size > 0) {
|
|
--_size;
|
|
}
|
|
}
|
|
|
|
CollisionInfo* CollisionList::getCollision(int index) {
|
|
return (index > -1 && index < _size) ? &(_collisions[index]) : NULL;
|
|
}
|
|
|
|
CollisionInfo* CollisionList::getLastCollision() {
|
|
return (_size > 0) ? &(_collisions[_size - 1]) : NULL;
|
|
}
|
|
|
|
void CollisionList::clear() {
|
|
// we rely on the external context to properly set or clear the data members of CollisionInfos
|
|
/*
|
|
for (int i = 0; i < _size; ++i) {
|
|
// we only clear the important stuff
|
|
CollisionInfo& collision = _collisions[i];
|
|
//collision._data = NULL;
|
|
//collision._intData = 0;
|
|
//collision._floatDAta = 0.0f;
|
|
//collision._vecData = glm::vec3(0.0f);
|
|
//collision._shapeA = NULL;
|
|
//collision._shapeB = NULL;
|
|
//collision._damping;
|
|
//collision._elasticity;
|
|
//collision._contactPoint;
|
|
//collision._penetration;
|
|
//collision._addedVelocity;
|
|
}
|
|
*/
|
|
_size = 0;
|
|
}
|
|
|
|
CollisionInfo* CollisionList::operator[](int index) {
|
|
return (index > -1 && index < _size) ? &(_collisions[index]) : NULL;
|
|
}
|