Files
2025-09-18 17:55:52 -04:00

183 lines
3.8 KiB
C++

/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#include "stdafx.h"
#include "V8World/MultiJoint.h"
#include "V8World/Primitive.h"
#include "V8World/Tolerance.h"
#include "V8Kernel/Kernel.h"
#include "V8Kernel/Connector.h"
#include "V8Kernel/Point.h"
namespace RBX {
void MultiJoint::init(int numBreaking)
{
numBreakingConnectors = numBreaking;
numConnector = 0;
for (int j = 0; j < 4; j++) {
point[j*2] = NULL;
point[j*2+1] = NULL;
connector[j] = NULL;
}
}
MultiJoint::MultiJoint(int numBreaking)
{
init(numBreaking);
}
MultiJoint::MultiJoint(
Primitive* p0,
Primitive* p1,
const CoordinateFrame& jointCoord0,
const CoordinateFrame& jointCoord1,
int numBreaking)
: Joint(p0, p1, jointCoord0, jointCoord1)
{
init(numBreaking);
}
MultiJoint::~MultiJoint()
{
RBXASSERT(connector[0] == NULL);
RBXASSERT(numConnector == 0);
}
void MultiJoint::putInKernel(Kernel* _kernel)
{
Super::putInKernel(_kernel);
}
float MultiJoint::getJointK()
{
return G3D::min( getPrimitive(0)->getJointK(), getPrimitive(1)->getJointK() );
}
void MultiJoint::addToMultiJoint(Point* point0, Point* point1, Connector* _connector)
{
RBXASSERT(numConnector < 4);
point[numConnector*2] = point0;
point[numConnector*2+1] = point1;
connector[numConnector] = _connector;
getKernel()->insertConnector(_connector);
numConnector++;
RBXASSERT_IF_VALIDATING(validateMultiJoint());
}
Point* MultiJoint::getPoint(int id)
{
RBXASSERT(id < 8);
RBXASSERT(point[id] != NULL);
RBXASSERT(point[id]->getBody() == getPrimitive(id % 2)->getBody());
return point[id];
}
Connector* MultiJoint::getConnector(int id)
{
RBXASSERT(id < 4);
RBXASSERT(connector[id] != NULL);
return connector[id];
}
#ifdef __RBX_VALIDATE_ASSERT
bool MultiJoint::pointsAligned() const
{
RBXASSERT(numBreakingConnectors <= numConnector);
// THIS ASSERT WILL BLOW in the situation where "unaligned" joints
// are present on save or sleep. For now, just watching to see how often
// this occurs
// If too often - will need to store joint information or implement wheel/holes
//
for (int i = 0; i < numBreakingConnectors; ++i) {
if (Tolerance::pointsUnaligned(
point[i*2]->getWorldPos(),
point[i*2+1]->getWorldPos())) {
return false;
}
}
return true;
}
#endif
bool MultiJoint::validateMultiJoint()
{
#ifdef _DEBUG
for (int i = 0; i < numConnector; ++i)
for (int j = 0; j < 2; ++j)
{{
Point *p = point[i*2 + j];
RBXASSERT(p->getBody() == this->getPrimitive(j)->getBody());
Connector* c = connector[i];
RBXASSERT(c->getBody((Connector::BodyIndex)j) == this->getPrimitive(j)->getBody());
}}
#endif
return true;
}
void MultiJoint::removeFromKernel()
{
RBXASSERT(this->inKernel());
// TODO - unsuppress this - indicates something that will NOT rejoin!
// RBXASSERT_IF_VALIDATING(pointsAligned());
RBXASSERT_IF_VALIDATING(validateMultiJoint());
for (int i = 0; i < numConnector; i++) {
RBXASSERT(connector[i]);
getKernel()->removeConnector(connector[i]);
delete connector[i];
getKernel()->deletePoint(point[i*2]);
getKernel()->deletePoint(point[i*2+1]);
point[i*2] = NULL;
point[i*2+1] = NULL;
connector[i] = NULL;
}
numConnector = 0;
Super::removeFromKernel();
RBXASSERT(!this->inKernel());
}
bool MultiJoint::isBroken() const
{
/// int max = std::min(numConnector, numBreakingConnectors);
RBXASSERT(numBreakingConnectors <= numConnector);
RBXASSERT(this->inKernel());
// ToDo: Saving joints, otherwise a save in this configuration could cause broken joints.
// RBXASSERT_IF_VALIDATING(pointsAligned());
for (int i = 0; i < numBreakingConnectors; ++i) {
RBXASSERT(connector[i]);
if (connector[i]->getBroken()) {
return true;
}
}
return false;
}
} // namespace
// Randomized Locations for hackflags
namespace RBX
{
namespace Security
{
unsigned int hackFlag10 = 0;
};
};