mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
151 lines
3.6 KiB
C++
151 lines
3.6 KiB
C++
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
|
#include "stdafx.h"
|
|
|
|
#include "V8World/PolyContact.h"
|
|
#include "V8Kernel/PolyConnectors.h"
|
|
#include "V8Kernel/Kernel.h"
|
|
#include "V8World/Primitive.h"
|
|
|
|
namespace RBX {
|
|
|
|
PolyContact::~PolyContact()
|
|
{
|
|
deleteConnectors(polyConnectors);
|
|
|
|
RBXASSERT(polyConnectors.size() == 0);
|
|
}
|
|
|
|
ContactConnector* PolyContact::getConnector(int i)
|
|
{
|
|
return polyConnectors[i];
|
|
}
|
|
|
|
void PolyContact::deleteAllConnectors()
|
|
{
|
|
deleteConnectors(polyConnectors);
|
|
}
|
|
|
|
|
|
void PolyContact::deleteConnectors(ConnectorArray& deleteConnectors)
|
|
{
|
|
removeAllConnectorsFromKernel();
|
|
|
|
for (size_t i = 0; i < deleteConnectors.size(); ++i) {
|
|
RBXASSERT(!deleteConnectors[i]->isInKernel());
|
|
delete deleteConnectors[i];
|
|
}
|
|
|
|
deleteConnectors.fastClear();
|
|
}
|
|
|
|
|
|
void PolyContact::removeAllConnectorsFromKernel()
|
|
{
|
|
Kernel* kernel = NULL;
|
|
for (size_t i = 0; i < polyConnectors.size(); ++i) {
|
|
if (polyConnectors[i]->isInKernel()) {
|
|
kernel = kernel ? kernel : getKernel(); // small optimization - getKernel walks the IPipelines
|
|
kernel->removeConnector(polyConnectors[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PolyContact::putAllConnectorsInKernel()
|
|
{
|
|
Kernel* kernel = NULL;
|
|
for (size_t i = 0; i < polyConnectors.size(); ++i) {
|
|
if (!polyConnectors[i]->isInKernel() &&
|
|
polyConnectors[i]->getContactPoint().length < -ContactConnector::overlapGoal()) {
|
|
kernel = kernel ? kernel : getKernel(); // small optimization - getKernel walks the IPipelines
|
|
kernel->insertConnector(polyConnectors[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool PolyContact::stepContact()
|
|
{
|
|
if (computeIsColliding(0.0f)) {
|
|
if (inKernel()) {
|
|
updateContactPoints();
|
|
putAllConnectorsInKernel();
|
|
}
|
|
return true;
|
|
}
|
|
else {
|
|
removeAllConnectorsFromKernel();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool PolyContact::computeIsColliding(float overlapIgnored)
|
|
{
|
|
if (Primitive::aaBoxCollide(*getPrimitive(0), *getPrimitive(1))) {
|
|
updateClosestFeatures();
|
|
if (polyConnectors.size() > 0) {
|
|
float overlap = worstFeatureOverlap();
|
|
if (overlap > overlapIgnored) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void PolyContact::updateClosestFeatures()
|
|
{
|
|
ConnectorArray newConnectors;
|
|
|
|
findClosestFeatures(newConnectors);
|
|
|
|
matchClosestFeatures(newConnectors); // new Connectors is now the deal!
|
|
|
|
RBXASSERT(newConnectors.size() <= 10);
|
|
|
|
deleteConnectors(polyConnectors); // any remaining not matched
|
|
|
|
polyConnectors = newConnectors; // transfer over the pointers
|
|
|
|
RBXASSERT(polyConnectors.size() <= 10);
|
|
}
|
|
|
|
float PolyContact::worstFeatureOverlap()
|
|
{
|
|
float worstOverlap = -FLT_MAX; // i.e. not overlapping
|
|
RBXASSERT(polyConnectors.size() > 0);
|
|
for (size_t i = 0; i < polyConnectors.size(); ++i) { // may not have any overlapping features!
|
|
float overlap = polyConnectors[i]->computeOverlap(); // computeLength returns negative
|
|
worstOverlap = std::max(worstOverlap, overlap);
|
|
}
|
|
return worstOverlap;
|
|
}
|
|
|
|
// TODO - turn optimizer back on here after fixed
|
|
void PolyContact::matchClosestFeatures(ConnectorArray& newConnectors)
|
|
{
|
|
for (size_t i = 0; i < newConnectors.size(); ++i) {
|
|
if (PolyConnector* match = matchClosestFeature(newConnectors[i])) {
|
|
delete newConnectors[i];
|
|
newConnectors.replace(i, match);
|
|
}
|
|
}
|
|
}
|
|
|
|
PolyConnector* PolyContact::matchClosestFeature(PolyConnector* newConnector)
|
|
{
|
|
for (size_t i = 0; i < polyConnectors.size(); ++i) {
|
|
PolyConnector* answer = polyConnectors[i];
|
|
if (PolyConnector::match(answer, newConnector)) {
|
|
polyConnectors.fastRemove(i);
|
|
return answer;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void PolyContact::updateContactPoints()
|
|
{
|
|
for (size_t i = 0; i < polyConnectors.size(); ++i)
|
|
polyConnectors[i]->updateContactPoint();
|
|
}
|
|
|
|
} // namespace
|